MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

CSS Flexbox弹性盒子布局的基础入门

2021-12-155.7k 阅读

什么是 CSS Flexbox 弹性盒子布局

CSS Flexbox,即弹性盒子布局模型,是一种用于在网页上创建灵活且自适应的布局的 CSS 模块。它旨在提供一种更高效的方式来布局、对齐和分配容器内项目的空间,即使容器的大小发生变化或者项目的大小未知。Flexbox 布局特别适用于一维布局,例如水平或垂直方向排列的元素,能够轻松实现居中对齐、等分布局等常见需求。

Flexbox 引入了两个主要概念:弹性容器(flex container)和弹性项目(flex item)。任何一个 CSS 盒模型元素,只要设置了 display: flexdisplay: inline - flex,就成为了一个弹性容器。弹性容器的直接子元素会自动成为弹性项目。

弹性容器的属性

display

用于定义一个元素为弹性容器。有两个值可用:

  • display: flex:将元素设置为块级弹性容器,容器会占据一整行。
  • display: inline - flex:将元素设置为行内弹性容器,容器宽度根据内容自适应。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
      }

    .flex - item {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Item 1</div>
    <div class="flex - item">Item 2</div>
    <div class="flex - item">Item 3</div>
  </div>
</body>

</html>

在上述代码中,.flex - container 通过 display: flex 变成了弹性容器,它内部的 .flex - item 成为了弹性项目,并且水平排列在容器内。

flex - direction

决定弹性项目在弹性容器内的排列方向。有四个取值:

  • row(默认值):弹性项目从左到右水平排列。
  • row - reverse:弹性项目从右到左水平排列。
  • column:弹性项目从上到下垂直排列。
  • column - reverse:弹性项目从下到上垂直排列。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        flex - direction: column;
      }

    .flex - item {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Item 1</div>
    <div class="flex - item">Item 2</div>
    <div class="flex - item">Item 3</div>
  </div>
</body>

</html>

这里通过设置 flex - direction: column,弹性项目变为垂直排列。

justify - content

用于控制弹性项目在主轴(由 flex - direction 定义的主要排列方向)上的对齐方式。有六个取值:

  • flex - start(默认值):弹性项目向主轴起始位置对齐。如果主轴是水平方向(row),则左对齐;如果主轴是垂直方向(column),则上对齐。
  • flex - end:弹性项目向主轴结束位置对齐。水平方向时右对齐,垂直方向时下对齐。
  • center:弹性项目在主轴上居中对齐。
  • space - between:弹性项目均匀分布在主轴上,两端对齐,项目之间间隔相等。
  • space - around:弹性项目均匀分布在主轴上,项目两侧间隔相等,看起来每个项目周围的间隔是均匀的。
  • space - even - ly:弹性项目均匀分布在主轴上,项目之间以及项目与容器两端的间隔都相等。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        justify - content: space - between;
      }

    .flex - item {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Item 1</div>
    <div class="flex - item">Item 2</div>
    <div class="flex - item">Item 3</div>
  </div>
</body>

</html>

上述代码通过 justify - content: space - between 使弹性项目在水平方向上均匀分布,两端对齐。

align - items

用于控制弹性项目在交叉轴(与主轴垂直的方向)上的对齐方式。有五个取值:

  • stretch(默认值):弹性项目会沿着交叉轴拉伸,以填满容器的交叉轴空间。前提是项目在交叉轴方向上没有设置固定高度或宽度。
  • flex - start:弹性项目向交叉轴起始位置对齐。
  • flex - end:弹性项目向交叉轴结束位置对齐。
  • center:弹性项目在交叉轴上居中对齐。
  • baseline:弹性项目根据它们的基线对齐。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        height: 200px;
        align - items: center;
      }

    .flex - item {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Item 1</div>
    <div class="flex - item">Item 2</div>
    <div class="flex - item">Item 3</div>
  </div>
</body>

</html>

在此示例中,通过 align - items: center 使弹性项目在垂直方向(交叉轴)上居中对齐。

flex - wrap

决定弹性项目是否换行。有三个取值:

  • nowrap(默认值):弹性项目不会换行,会尽量在一行(或一列)内显示,可能导致项目被压缩。
  • wrap:弹性项目在容器空间不足时会换行,第一行在上方(如果主轴是水平方向)或左侧(如果主轴是垂直方向)。
  • wrap - reverse:弹性项目在容器空间不足时会换行,第一行在下方(如果主轴是水平方向)或右侧(如果主轴是垂直方向)。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        width: 300px;
        flex - wrap: wrap;
      }

    .flex - item {
        background - color: lightgreen;
        width: 150px;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Item 1</div>
    <div class="flex - item">Item 2</div>
    <div class="flex - item">Item 3</div>
  </div>
</body>

</html>

由于设置了 flex - wrap: wrap,当容器宽度不足以容纳所有项目时,项目会自动换行。

align - content

当弹性容器有多行(或多列,如果主轴是垂直方向)时,align - content 用于控制这些行在交叉轴上的对齐方式。有六个取值:

  • stretch(默认值):各行会拉伸以填满交叉轴空间。
  • flex - start:各行向交叉轴起始位置对齐。
  • flex - end:各行向交叉轴结束位置对齐。
  • center:各行在交叉轴上居中对齐。
  • space - between:各行均匀分布在交叉轴上,两端对齐,行与行之间间隔相等。
  • space - around:各行均匀分布在交叉轴上,行两侧间隔相等。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        height: 400px;
        flex - wrap: wrap;
        align - content: space - between;
      }

    .flex - item {
        background - color: lightgreen;
        width: 150px;
        height: 100px;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Item 1</div>
    <div class="flex - item">Item 2</div>
    <div class="flex - item">Item 3</div>
    <div class="flex - item">Item 4</div>
  </div>
</body>

</html>

在上述代码中,通过 align - content: space - between 使多行弹性项目在垂直方向(交叉轴)上均匀分布,两端对齐。

弹性项目的属性

order

order 属性用于控制弹性项目在弹性容器中的排列顺序。默认值为 0,值越小,项目越靠前排列。可以为负值。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
      }

    .flex - item1 {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
        order: 2;
      }

    .flex - item2 {
        background - color: orange;
        padding: 10px;
        margin: 5px;
        order: 1;
      }

    .flex - item3 {
        background - color: pink;
        padding: 10px;
        margin: 5px;
        order: 3;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item1">Item 1</div>
    <div class="flex - item2">Item 2</div>
    <div class="flex - item3">Item 3</div>
  </div>
</body>

</html>

在这个例子中,通过设置不同的 order 值,改变了弹性项目的默认排列顺序,Item 2 排在了最前面。

flex - grow

flex - grow 属性定义弹性项目的放大比例。默认值为 0,表示如果有剩余空间,也不放大。如果所有项目的 flex - grow 值都为 1,它们将等比例放大,填满剩余空间。如果某个项目的 flex - grow 值为 2,而其他项目为 1,那么该项目将占据两倍于其他项目的剩余空间。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
      }

    .flex - item1 {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
        flex - grow: 2;
      }

    .flex - item2 {
        background - color: orange;
        padding: 10px;
        margin: 5px;
        flex - grow: 1;
      }

    .flex - item3 {
        background - color: pink;
        padding: 10px;
        margin: 5px;
        flex - grow: 1;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item1">Item 1</div>
    <div class="flex - item2">Item 2</div>
    <div class="flex - item3">Item 3</div>
  </div>
</body>

</html>

在上述代码中,Item 1flex - grow 值为 2,Item 2Item 3flex - grow 值为 1,因此 Item 1 占据的剩余空间是 Item 2Item 3 的两倍。

flex - shrink

flex - shrink 属性定义弹性项目的缩小比例。默认值为 1,表示当空间不足时,项目会缩小。如果所有项目的 flex - shrink 值都为 1,它们将等比例缩小。如果某个项目的 flex - shrink 值为 0,那么在空间不足时,该项目不会缩小。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        width: 300px;
      }

    .flex - item1 {
        background - color: lightgreen;
        width: 150px;
        padding: 10px;
        margin: 5px;
        flex - shrink: 0;
      }

    .flex - item2 {
        background - color: orange;
        width: 150px;
        padding: 10px;
        margin: 5px;
        flex - shrink: 1;
      }

    .flex - item3 {
        background - color: pink;
        width: 150px;
        padding: 10px;
        margin: 5px;
        flex - shrink: 1;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item1">Item 1</div>
    <div class="flex - item2">Item 2</div>
    <div class="flex - item3">Item 3</div>
  </div>
</body>

</html>

在这个例子中,由于容器宽度为 300px,而三个项目总宽度为 450px(每个项目 150px),空间不足。Item 1flex - shrink 值为 0,不会缩小,Item 2Item 3flex - shrink 值为 1,会等比例缩小以适应容器宽度。

flex - basis

flex - basis 属性定义在分配多余空间之前,弹性项目的初始主尺寸。可以设置具体的长度值(如 pxem 等),也可以使用 auto(默认值),表示根据项目内容自动计算尺寸。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
      }

    .flex - item1 {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
        flex - basis: 200px;
      }

    .flex - item2 {
        background - color: orange;
        padding: 10px;
        margin: 5px;
        flex - basis: auto;
      }

    .flex - item3 {
        background - color: pink;
        padding: 10px;
        margin: 5px;
        flex - basis: 150px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item1">Item 1</div>
    <div class="flex - item2">Item 2</div>
    <div class="flex - item3">Item 3</div>
  </div>
</body>

</html>

在上述代码中,Item 1 的初始宽度被设置为 200px,Item 3 为 150px,Item 2 根据内容自动计算宽度。

flex

flexflex - growflex - shrinkflex - basis 的简写属性。常见的用法有:

  • flex: 0 1 auto:这是默认值,等同于分别设置 flex - grow: 0flex - shrink: 1flex - basis: auto
  • flex: 1:等同于 flex: 1 1 0%,表示项目会放大和缩小,并且初始尺寸为 0,会根据剩余空间分配大小。
  • flex: auto:等同于 flex: 1 1 auto,项目会放大和缩小,并且初始尺寸根据内容自动计算。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
      }

    .flex - item1 {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
        flex: 1;
      }

    .flex - item2 {
        background - color: orange;
        padding: 10px;
        margin: 5px;
        flex: 2;
      }

    .flex - item3 {
        background - color: pink;
        padding: 10px;
        margin: 5px;
        flex: 1;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item1">Item 1</div>
    <div class="flex - item2">Item 2</div>
    <div class="flex - item3">Item 3</div>
  </div>
</body>

</html>

在此示例中,Item 2flex 值为 2,会占据比 Item 1Item 3 更多的剩余空间,因为它的 flex - grow 值相对较大。

align - self

align - self 属性允许单个弹性项目覆盖容器的 align - items 属性。取值与 align - items 相同,有 stretchflex - startflex - endcenterbaseline

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        height: 200px;
        align - items: stretch;
      }

    .flex - item1 {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
        align - self: center;
      }

    .flex - item2 {
        background - color: orange;
        padding: 10px;
        margin: 5px;
      }

    .flex - item3 {
        background - color: pink;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item1">Item 1</div>
    <div class="flex - item2">Item 2</div>
    <div class="flex - item3">Item 3</div>
  </div>
</body>

</html>

在上述代码中,容器设置了 align - items: stretch,但 Item 1 通过 align - self: center 使其在交叉轴上居中对齐,而 Item 2Item 3 仍遵循容器的 align - items 设置进行拉伸。

Flexbox 的常见应用场景

水平居中对齐

要实现水平居中对齐,只需将弹性容器的 justify - content 属性设置为 center 即可。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        justify - content: center;
      }

    .flex - item {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Centered Item</div>
  </div>
</body>

</html>

垂直居中对齐

实现垂直居中对齐,将弹性容器的 align - items 属性设置为 center

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        height: 200px;
        align - items: center;
      }

    .flex - item {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Vertically Centered Item</div>
  </div>
</body>

</html>

水平垂直居中对齐

同时实现水平和垂直居中对齐,将弹性容器的 justify - content 设置为 centeralign - items 设置为 center

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        height: 200px;
        justify - content: center;
        align - items: center;
      }

    .flex - item {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Centered Item</div>
  </div>
</body>

</html>

等分布局

通过 justify - content: space - betweenjustify - content: space - around 可以实现等分布局。

示例代码(使用 space - between):

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        justify - content: space - between;
      }

    .flex - item {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Item 1</div>
    <div class="flex - item">Item 2</div>
    <div class="flex - item">Item 3</div>
  </div>
</body>

</html>

示例代码(使用 space - around):

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
        justify - content: space - around;
      }

    .flex - item {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Item 1</div>
    <div class="flex - item">Item 2</div>
    <div class="flex - item">Item 3</div>
  </div>
</body>

</html>

响应式布局

结合媒体查询和 Flexbox,可以轻松创建响应式布局。例如,在不同屏幕宽度下改变弹性项目的排列方向。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .flex - container {
        display: flex;
        background - color: lightblue;
      }

    @media (max - width: 600px) {
      .flex - container {
          flex - direction: column;
        }
    }

    .flex - item {
        background - color: lightgreen;
        padding: 10px;
        margin: 5px;
      }
  </style>
</head>

<body>
  <div class="flex - container">
    <div class="flex - item">Item 1</div>
    <div class="flex - item">Item 2</div>
    <div class="flex - item">Item 3</div>
  </div>
</body>

</html>

在上述代码中,当屏幕宽度小于等于 600px 时,弹性项目会从水平排列变为垂直排列。

兼容性及注意事项

Flexbox 在现代浏览器中得到了广泛支持,但在一些较旧的浏览器中可能存在兼容性问题。可以使用浏览器前缀来处理兼容性,例如 -webkit -(用于 Safari)、-moz -(用于 Firefox)、-ms -(用于 Internet Explorer)。

例如,要在 Safari 中使用 Flexbox,可能需要这样写:

.flex - container {
  display: -webkit - flex;
  display: flex;
  -webkit - justify - content: center;
  justify - content: center;
}

在使用 Flexbox 时,还需要注意以下几点:

  • 弹性项目的 floatclearvertical - align 属性将失效,因为 Flexbox 有自己的布局和对齐规则。
  • 当设置 flex - direction: column 时,主轴变为垂直方向,交叉轴变为水平方向,此时 justify - contentalign - items 的作用方向会相应改变。
  • 避免过度嵌套 Flexbox 容器,因为这可能会导致布局复杂度增加,影响性能。

通过掌握 CSS Flexbox 弹性盒子布局,前端开发者可以更高效地创建各种灵活、自适应的网页布局,提升用户体验,并且更好地适应不同设备和屏幕尺寸的需求。