CSS Handbook · 布局

第六章 / 6.3 Flexbox 详解

第六章 · 6.3 节

Flexbox 详解


Flexbox(弹性盒布局)是为一维排布而生的系统:无论是一行导航链接、一组等高卡片,还是一个需要在容器中垂直水平都居中的元素,Flexbox 都能用寥寥几行声明式代码解决,彻底终结了 float 时代靠 hack 凑布局的历史。

主轴与交叉轴

理解 Flexbox 的第一把钥匙,是分清"主轴"(main axis)与"交叉轴"(cross axis)——几乎所有 flex 属性都是围绕这两条轴展开的。

flex-direction: row(默认)时的轴向
↑ 交叉轴
1
2
3
主轴 →

flex-direction 决定主轴方向:row(水平,默认)、column(垂直)、以及它们的 -reverse 版本。交叉轴永远与主轴垂直——当主轴变为垂直方向时,"justify-content 控制水平"这类记忆方式就会失效,务必以主轴/交叉轴而非"水平/垂直"来理解。

容器属性

属性作用常用取值
display开启弹性布局flex / inline-flex
flex-direction主轴方向row / column / row-reverse
flex-wrap是否允许换行nowrap(默认)/ wrap
justify-content主轴对齐flex-start / center / space-between / space-around / space-evenly
align-items交叉轴对齐(单行)stretch(默认)/ center / flex-start / flex-end / baseline
align-content交叉轴对齐(多行整体)同 justify-content 取值,需配合 wrap
gap子项间距如 16px,或 row-gap/column-gap 分别设置
justify-content 对比
flex-start
A
B
center
A
B
space-between
A
B

子项属性

属性作用
order调整视觉排列顺序,不改变 DOM 顺序,默认值 0
align-self覆盖容器的 align-items,单独控制某一项的交叉轴对齐
flex-grow剩余空间的分配比例,默认 0(不主动拉伸)
flex-shrink空间不足时的收缩比例,默认 1(允许收缩)
flex-basis分配剩余空间前的"起始尺寸",默认 auto

grow / shrink / basis 换算

这三者常合写为简写 flex: grow shrink basis,是 Flexbox 中最容易"知道语法但不知道为什么"的部分。理解它的关键是想象一条计算流程:

  1. 浏览器先按每个子项的 flex-basis 计算"期望尺寸"之和;
  2. 与容器主轴尺寸比较:若有剩余空间,按 flex-grow 的比例分配给各子项;
  3. 若空间不足,则按 flex-shrink(并结合各自 basis 加权)的比例收缩各子项。
/* 常见简写 */
.item { flex: 1; }          /* 等价于 1 1 0%,均分剩余空间 */
.item { flex: auto; }       /* 等价于 1 1 auto,按内容尺寸伸缩 */
.item { flex: none; }       /* 等价于 0 0 auto,完全不伸缩 */
.item { flex: 0 0 200px;  } /* 固定 200px,不参与伸缩 */
flex: 1 1 0% — 三项均分剩余空间
flex: 1
flex: 1
flex: 1
flex: 2 1 0 / 1 1 0 / 1 1 0 — 按 2:1:1 分配
2
1
1

gap 间距

gap 出现之前,子项间距只能靠 margin 拼凑,还得处理"最后一项不需要间距"的边界情况。现在 gap 原生支持行列间距,且不会在容器边缘产生多余空白。

.container {
  display: flex;
  gap: 12px 20px; /* row-gap column-gap */
}

常见排布方案

方案一:导航栏两端对齐

.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

方案二:完全居中

.center-box {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

方案三:等高卡片 + 底部按钮对齐

.card {
  display: flex;
  flex-direction: column;
}
.card .spacer { flex: 1; } /* 把按钮推到底部 */
效果预览:卡片内容不等长,按钮仍底部对齐
短标题
按钮
这是一段比较长的标题文字,会占用更多行
按钮

常见误区

  • 子项设置了固定宽度,却仍被 flex-shrink 压缩——记得配合 flex-shrink: 0min-width: 0 排查。
  • align-items 默认值是 stretch,若子项高度"莫名"被拉伸,先检查是否显式设置了它。
  • 文本或图片子项不换行导致溢出,往往是因为 flex 子项的默认最小尺寸是内容尺寸,需要设置 min-width: 0overflow 处理。