awfufu

返回

CSS Flex 布局Blur image

flex 布局#

块级元素和行内元素#

块级元素:独占一行(前后会自动换行),自动填满父容器的宽度。它们的 display 属性为 block。 行内元素:与其他行内元素排在一行内,宽高由内容决定。它们的 display 属性为 inline

大部分 html 元素都是块级元素或行内元素。

下面是一个例子,一个 container 中装了 3 个 item。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
html

这里的 item 都是块级元素,它们都独占一行,自上而下排列。

为了方便展示,示例中的 container 容器使用 红色边框,其中的 item 项目使用 蓝色方块

1
2
3

flex 容器和 flex 元素#

在容器元素的 CSS 中添加 display: flex,它就会变为 flex 容器。

flex 容器的直接子项目都是 flex 元素。

.container {
  display: flex;
}
css

可以看到,flex 容器中的 item 项目会自动排列在一行内。

1
2
3

flex 容器的主轴#

flex 布局的主轴默认为水平方向,主轴方向由 flex-direction 属性控制,默认为 row

.container {
  display: flex;
  flex-direction: row;
}
css
1
2
3
Start
End

如果将主轴方向 flex-direction 设为 row-reverse(翻转),那么元素则会反方向排列。

.container {
  display: flex;
  flex-direction: row-reverse;
}
css
1
2
3

沿轴线方向对齐#

沿主轴对齐#

flex 容器内的元素会沿着主轴方向排列,在 flex 容器上使用 justify-content 属性可以控制容器内元素在主轴上的位置。justify-content 有以下几个常用的取值。

  1. start:对齐主轴起点,这是默认行为。
.container {
  display: flex;
  justify-content: start;
}
css
1
2
3
Start
End
  1. end:对齐主轴终点。
.container {
  display: flex;
  justify-content: end;
}
css
1
2
3
Start
End
  1. center:在主轴上居中。
.container {
  display: flex;
  justify-content: center;
}
css
1
2
3
Start
End
  1. space-between:均匀分配每个 item 的间隙(item 之间)。
.container {
  display: flex;
  justify-content: space-between;
}
css

两侧不留间隙,只在 item 之间均匀分配。

1
2
3
  1. space-around:均匀分配每个 item 两侧的空间(周围)。
.container {
  display: flex;
  justify-content: space-around;
}
css

item 之间的间隙是侧边的两倍。

1
2
3
  1. space-evenly:均匀分配每个 item 的间隙(包括侧边的)。
.container {
  display: flex;
  justify-content: space-evenly;
}
css

两侧留出间隙,所有间隙都均匀分配。

1
2
3
  1. gap:手动设置间隙

手动指定 flex 元素之间的间隙。

.container {
  display: flex;
  gap: 20px;
}
css
1
2
3

沿交叉轴对齐#

交叉轴垂直于主轴,使用 align-items 属性可以调整元素在交叉轴上的对齐方式。

为了方便展示纵向对齐,这里增加了 容器边框 的高度。

  1. 对齐交叉轴起点

align-items 的默认值也是 start

.container {
  display: flex;
  align-items: start;
}
css
1
2
3
  1. 对齐交叉轴终点
.container {
  display: flex;
  align-items: end;
}
css
1
2
3
  1. 居中对齐
.container {
  display: flex;
  align-items: center;
}
css
1
2
3

同时使用 justify-content: centeralign-items: center,可以轻松让元素水平垂直居中。

.container {
  display: flex;
  justify-content: center;
  align-items: center;
}
css
1
2
3

旋转主轴方向#

设置 flex-directioncolumn,可以将主轴方向设为纵向,交叉轴方向同时变为横向。

.container {
  display: flex;
  flex-direction: column;
}
css
1
2
3

由于现在的交叉轴是横向的,所以此时要让元素水平居中,应该调整 align-content 而不是 justify-content

.container {
  display: flex;
  flex-direction: column;
  align-items: center;
}
css
1
2
3

justify-content 现在调整的是纵向的主轴,即垂直方向的对齐方式。

.container {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
css
1
2
3

多行布局#

flex 自动换行#

给 flex 容器使用 flex-wrap 属性,可以控制 flex 元素是否自动换行。

flex-wrap 的默认值为 nowrap,当容器空间不足(比如手机屏幕,横向空间较小)时,会压扁(收缩)其中的元素。如果元素无法被压缩,会直接溢出容器。

.container {
  display: flex;
  gap: 40px;
  flex-wrap: nowrap;
}
css

如果你正在使用电脑浏览这个页面,你可以试试拖动浏览器窗口右侧,改变页面宽度,观察下面的元素会发生什么。

1
2
3
4
5
6
7
8
9

flex-wrap 设为 wrap,元素会自动在空间不足时换行。

.container {
  display: flex;
  flex-wrap: wrap;
  gap: 40px;
  max-width: 400px; /* 限制宽度方便展示换行 */
}
css
1
2
3
4
5
6
7
8
9

多行布局下的对齐方式#

就像主轴上有 justify-content 属性一样,交叉轴上也有 align-content属性,它可以控制交叉轴上整体的对齐方式。

现在有以下示例,在一个 flex 容器中装了 9 个元素,让它们自动换行,现在不使用 gap

.container {
  display: flex;
  flex-wrap: wrap;
  max-width: 320px;
  height:450px;
}
css
1
2
3
4
5
6
7
8
9

align-content 默认为 stretch,所以可以发现即使不使用 gap,元素在垂直方向上依然有间隙。

align-content 同样也有 startendcenter 取值,让元素整体在交叉轴上对齐。比如,下面使用 align-content: center 让元素在交叉轴上居中对齐。

.container {
  /* ... */
  align-content: center;
}
css
1
2
3
4
5
6
7
8
9

前面说过,align-items 也是用来调整交叉轴上的对齐方式的,那么它和 align-content 的区别是什么呢?

尝试用 align-items 替代 align-content

.container {
  /* ... */
  align-items: center;
}
css
1
2
3
4
5
6
7
8
9
.container {
  /* ... */
  align-items: end;
}
css
1
2
3
4
5
6
7
8
9
.container {
  /* ... */
  align-items: start;
}
css
1
2
3
4
5
6
7
8
9

结合上面三个例子不难看出,align-items 控制的 startendcenter 让元素对齐了它们各自的交叉轴。

其实在 wrap 自动换行后,每一行(如果设置了纵向主轴则是列)元素都有它们自己独立的主轴和交叉轴。此时 align-items 调整的是各行元素在自身的交叉轴上的对齐方式,而 align-content 调整的是多行元素整体在交叉轴上的对齐方式。

所以,如果要将元素完全居中对齐,我们应该在 flex 容器上设置以下三个 center 值:

.container {
  /* ... */
  justify-content: center;
  align-items: center;
  align-content: center;

  /* 这里适当添加 gap,看起来更美观 */
  gap: 10px;
}
css
1
2
3
4
5
6
7
8
9

拉伸和收缩元素#

自动拉伸#

如果想要让元素自动拉伸以填满容器的剩余空间,可以使用 flex-grow 属性。

flex-grow 的默认值为 0,即禁用自动拉伸。

.item {
  flex-grow: 0;
}
css
1
2
3

flex-grow 设为 1 时,元素将会自动拉伸以填满容器空间。注意 flex-grow 属性是加在 item 元素身上的,而不是 flex 容器上。

.item {
  flex-grow: 1;
}
css
1
2
3

也可以指定拉伸其中某个元素,其他不拉伸,比如只在第二个元素上添加 flex-grow: 1

.item {
  flex-grow: 0;
}

#item-2 {
  flex-grow: 1;
}
css
1
2
3

自动收缩#

flex 容器中的元素在空间不足时会自动收缩,自动收缩由 flex-shrink 属性控制,其默认值为 1,即:

.item {
  flex-shrink: 1;
}
css

注意 flex-shrink 属性是加在元素身上的,而不是 flex 容器上。

1
2
3

如果要禁用自动压缩,可以设置 flex-shrink: 0

.item {
  flex-shrink: 0;
}
css
1
2
3

按比例拉伸或收缩#

在同时存在多个 item 时,flex-growflex-shrink 的数值是有意义的,通过给它们设置不同的值,可以实现按比例拉伸或收缩。

<div class="container">
  <div class="item" style="flex-grow:1;">1</div>
  <div class="item" style="flex-grow:3;">2</div>
  <div class="item" style="flex-grow:5;">3</div>
</div>
html

这样每个元素被拉伸的空间比例为 1:3:5。注意:这并不是说元素占用的空间是 1:3:5,而是它们被拉伸的空间是按这个比例分配的。

1
2
3

按比例收缩同理,数值越大被压缩的越多。

<div class="container">
  <div class="item" style="flex-shrink:1;">1</div>
  <div class="item" style="flex-shrink:3;">2</div>
  <div class="item" style="flex-shrink:5;">3</div>
</div>
html
1
2
3
CSS Flex 布局
https://awfufu.com/blog/css-flex-layout
Author awfufu
Published at 2025年11月25日
Comment seems to stuck. Try to refresh?✨