第六章 · 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 中最容易"知道语法但不知道为什么"的部分。理解它的关键是想象一条计算流程:
- 浏览器先按每个子项的
flex-basis计算"期望尺寸"之和; - 与容器主轴尺寸比较:若有剩余空间,按
flex-grow的比例分配给各子项; - 若空间不足,则按
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: 0或min-width: 0排查。 align-items默认值是stretch,若子项高度"莫名"被拉伸,先检查是否显式设置了它。- 文本或图片子项不换行导致溢出,往往是因为 flex 子项的默认最小尺寸是内容尺寸,需要设置
min-width: 0或overflow处理。