CSS FlexBox 弹性盒子

Flexible Box 模型,通常被称为 flexbox 或弹性盒子,是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。

Flexible Box 模型,通常被称为 flexbox 或弹性盒子,是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。

CSS Flexbox 布局模块

之前了解的 4 种布局模式:

  • 块,用于网页中的一个部分
  • 内联,用于文本
  • 表格,用于二维表格数据
  • 定位,用于元素的显式位置

而 Flex 布局,可以更轻松地设计灵活的响应式布局结构,而无需使用浮动或定位。

Flex 弹性布局

要使用 flex 弹性布局,需要有弹性容器和弹性元素。 弹性容器是设置了 display: flex; 规则的元素,而包含在弹性容器中的子元素则是弹性元素。

下面的例子中,<div class="flex-container"> 元素就是弹性容器,而弹性元素则是 <div>1</div><div>2</div><div>3</div> 这 3 个元素。

一个包含三个项目的 Flex 容器:

<style>
  .flex-container {
    display: flex;
  }
</style>

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

弹性容器 flex container

Flex 弹性容器是声明了 display: flex; CSS 规则的元素,是 Flex 弹性元素的直接上级元素。

弹性容器属性有:

flex-direction

flex-direction 属性定义了容器中弹性元素堆叠的方向。

flex-direction 属性可选值:

  • column : 弹性元素从上到下垂直排列
  • column-reverse: 弹性元素从下到上垂直排列
  • row: 弹性元素从左到右水平排列
  • row-reverse: 弹性元素从右到左水平排列

column 值垂直堆叠 flex 项目(从上到下):

<style>
  .flex-container1 {
    display: flex;
    flex-direction: column;
  }

  .flex-container2 {
    display: flex;
    flex-direction: column-reverse;
  }

  .flex-container3 {
    display: flex;
    flex-direction: row;
  }

  .flex-container4 {
    display: flex;
    flex-direction: row-reverse;
  }
</style>

<div class="flex-container1">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>
<div class="flex-container2">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>
<div class="flex-container3">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>
<div class="flex-container4">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

flex-wrap

flex-wrap 属性指定弹性元素是否应换行。可选值有:

  • nowrap: 默认值。所有弹性元素被摆放到到一行,这可能导致溢出 flex 容器。
  • wrap: 弹性元素在必要时可以换行。
  • wrap-reverse: 弹性元素在必要时可以换行,但是排列顺序相反。
.flex-container1 {
  display: flex;
  flex-wrap: wrap;
}

.flex-container2 {
  display: flex;
  flex-wrap: nowrap;
}

.flex-container3 {
  display: flex;
  flex-wrap: wrap-reverse;
}

flex-flow

flex-flow 属性是 flex-directionflex-wrap 的简写属性。

.flex-container {
  display: flex;
  flex-flow: row wrap;
}

justify-content

justify-content 属性用于定义弹性容器主轴(横轴)方向上元素之间的空间的分配方式。常用的属性值有:

  • flex-start: 默认值。从行首开始排列。每行第一个弹性元素与行首对齐,同时所有后续的弹性元素与前一个对齐。
  • flex-end: 从行尾开始排列。每行最后一个弹性元素与行尾对齐,其他元素将与后一个对齐。
  • center: 将 flex 弹性元素容器居中对齐。每行第一个元素到行首的距离将与每行最后一个元素到行尾的距离相同。
  • space-around: 在每行上均匀分配弹性元素。相邻元素间距离相同。每行第一个元素到行首的距离和每行最后一个元素到行尾的距离将会是相邻元素之间距离的一半。
  • space-between: 在每行上均匀分配弹性元素。相邻元素间距离相同。每行第一个元素与行首对齐,每行最后一个元素与行尾对齐。

弹性元素主轴对齐实例:

.flex-container {
  display: flex;
}

.center {
  justify-content: center;
}

.flex-start {
  justify-content: flex-start;
}

.flex-end {
  justify-content: flex-end;
}

.space-around {
  justify-content: space-around;
}

.space-between {
  justify-content: space-between;
}

align-items

align-items 定义弹性元素沿弹性容器侧轴(纵轴)的对齐方式。常用的属性值有:

  • stretch 默认值。弹性元素被在侧轴方向被拉伸到与容器相同的高度或宽度。
  • center: 元素在侧轴居中。如果元素在侧轴上的高度高于其容器,那么在两个方向上溢出距离相同。
  • flex-start: 元素向侧轴起点对齐。
  • flex-end: 元素向侧轴终点对齐。
  • baseline: 所有元素向基线对齐。侧轴起点到元素基线距离最大的元素将会于侧轴起点对齐以确定基线。

下面的示例中,为了更好地演示 align-items 属性,我们使用 200 像素高的容器。

.flex-container {
  display: flex;
  height: 200px;
}

.center {
  align-items: center;
}

.flex-start {
  align-items: flex-start;
}

.flex-end {
  align-items: flex-end;
}

.stretch {
  align-items: stretch;
}

.baseline {
  align-items: baseline;
}

align-content

align-content 属性用于定义弹性容器侧轴(纵轴)方向上元素之间的空间的分配方式,如果弹性盒子为只有一行弹性元素,此属性不起作用。常用的属性值有:

  • flex-start: 默认值。所有行从侧轴起点开始填充。第一行的侧轴起点边和容器的侧轴起点边对齐。接下来的每一行紧跟前一行。
  • flex-end: 所有行从侧轴末尾开始填充。最后一行的侧轴终点和容器的侧轴终点对齐。同时所有后续行与前一个对齐。
  • center: 所有行朝向容器的中心填充。每行互相紧挨,相对于容器居中对齐。容器的侧轴起点边和第一行的距离相等于容器的侧轴终点边和最后一行的距离。
  • stretch: 拉伸所有行来填满剩余空间。剩余空间平均地分配给每一行。
  • space-around: 所有行在容器中平均分布,相邻两行间距相等。容器的侧轴起点边和终点边分别与第一行和最后一行的距离是相邻两行间距的一半。
  • space-between: 所有行在容器中平均分布。相邻两行间距相等。容器的侧轴起点边和终点边分别与第一行和最后一行的边对齐。
  • space-evenly: 所有行沿侧轴均匀分布在对齐容器内。每对相邻的项之间的间距,主开始边和第一项,以及主结束边和最后一项,都是完全相同的。
.flex-container {
  display: flex;
  height: 600px;
  flex-wrap: wrap;
  align-content: space-between;
}

.flex-start {
  align-content: flex-start;
}

.flex-end {
  align-content: flex-end;
}

.center {
  align-content: center;
}

.stretch {
  align-content: stretch;
}

.space-between {
  align-content: space-between;
}

.space-around {
  align-content: space-around;
}

.space-evenly {
  align-content: space-around;
}

完美对中

在下面的例子中,我们将解决一个非常常见的样式问题:完美居中。

**解决方案:**将 justify-contentalign-items 属性都设置为 center,弹性元素将完美居中:

.flex-container {
  display: flex;
  height: 300px;
  justify-content: center;
  align-items: center;
}

弹性元素 flex items

弹性容器的直接子元素会自动变成弹性元素。

弹性元素属性有:

order

order 属性设置弹性容器中的可伸缩项目在布局时的顺序。元素按照 order 属性的值从小到大的顺序进行布局。拥有相同 order 属性值的元素按照它们在源代码中出现的顺序进行布局。

使用 order 属性改变弹性元素的显示顺序:

<div class="flex-container">
  <div style="order: 3">1</div>
  <div style="order: 2">2</div>
  <div style="order: 4">3</div>
  <div style="order: 1">4</div>
</div>

!! order 仅仅对元素的视觉顺序产生作用,并不会影响元素的逻辑或 tab 顺序。 order 不可以用于非视觉媒体,例如 屏幕阅读器。

flex-grow

flex-grow 属性设置一个弹性元素的增长系数。弹性容器中的剩余空间会按照所有弹性元素的增长系统的比例分配给弹性元素。

flex-grow 属性的值必须是数字,不能是负数,默认值为 0。flex-grow 属性的值为 0 表示弹性元素不可增长。

<div class="flex-container">
  <div style="flex-grow: 1">1</div>
  <div style="flex-grow: 1">2</div>
  <div style="flex-grow: 8">3</div>
</div>

利用 flex-grow 属性,我们可以很容易做出一个侧边栏宽度固定,内容去自动变化的布局:

<style>
  * {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }
  #container {
    display: flex;
    height: 100vh;
    width: 100vw;
  }
  #side {
    width: 200px;
    border-right: 1px solid gray;
    background: lightgray;
  }
  #main {
    flex-grow: 1;
  }
</style>

<div id="container">
  <div id="side">侧边栏</div>
  <div id="main">内容区</div>
</div>

例子中,#side 只设置了宽度,flex-grow 为默认值 0 ,也就是不参与分配剩余空间。 #main 没有指定具体的宽度,但是 flex-grow 设置为 1,那么剩余空间全部分配给 #main 元素了。

flex-shrink

flex-shrink 属性设置了弹性元素的收缩规则。弹性元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值。

flex-shrink 属性的值必须是数字,不能是负数,默认值为 1。 flex-shrink 属性的值为 0 表示弹性元素不可收缩。

第三个弹性元素不收缩:

<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div style="flex-shrink: 0">3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
  <div>10</div>
</div>

flex-basis

flex-basis 属性指定弹性元素在主轴方向上的初始大小。

第三个弹性元素的初始长度设置为 200 像素:

<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div style="flex-basis: 200px; width: 150px;">3</div>
  <div>4</div>
</div>

!! 当一个元素同时被设置了 flex-basis (除值为 auto 外) 和 width (或者在 flex-direction: column 情况下设置了 height) , flex-basis 具有更高的优先级。上例中的 width: 150px; 并未生效。

flex

flex 属性是 flex-growflex-shrinkflex-basis 的简写属性。

第三个 flex 项不可增长 (0),不可收缩 (0),初始长度为 200 像素:

<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div style="flex: 0 0 200px">3</div>
  <div>4</div>
</div>

align-self

align-self 属性设置当前弹性元素沿弹性容器侧轴(纵轴)的对齐方式

align-self 属性会覆盖弹性容器 align-items 属性设置的默认对齐方式。

在下面的例子中,第 1 个和第 4 个 <div> 元素继承了容器的默认的对齐方式 align-items: stretch;, 第 2 个元素对齐到容器顶部,第 3 个元素对齐到容器的底部。

设置弹性元素在纵轴的对齐方式:

<div class="flex-container">
  <div>1</div>
  <div style="align-self: flex-start">2</div>
  <div style="align-self: flex-end">3</div>
  <div>4</div>
</div>

浏览器支持情况

所有现代浏览器都支持 flexbox 属性。

Chrome IE Firefox Safari Opera
29.0 11.0 22.0 10 48