Flex 布局:12 个属性分工
Flexbox 是 容器定方向,子项定大小 两套属性加起来 12 个的事。
- 启动:
display: flex一行,元素变弹性容器 - 容器 6 属性:flex-direction / flex-wrap / justify-content / align-items / align-content / gap
- 子项 6 属性:flex-grow / flex-shrink / flex-basis / flex / order / align-self
- 核心思路:先想主轴(默认水平),再选对齐方式
- 现代选择:
gap替代margin间距 - 常见坑:主轴 / 交叉轴搞反,90% 的 flex bug 都是这个
- 默认行为:grow=0 / shrink=1(不抢必缩)
启动:display: flex
.container { display: flex; }
一行,直接子元素 变 flex item,参与弹性布局。inline-flex 是行内版本(容器本身按 inline 处理)。
下面是一张经典的 Flexbox 速查图,把所有 12 个属性的常见值摆在一起,可以作为后面属性表的视觉参考:
两套属性,12 个
容器属性(写在 display: flex 的元素上):
| 属性 | 作用 | 常见值 |
|---|---|---|
flex-direction | 主轴方向 | row / column / row-reverse / column-reverse |
flex-wrap | 是否换行 | nowrap / wrap / wrap-reverse |
justify-content | 主轴 对齐 | flex-start / center / flex-end / space-between / space-around |
align-items | 交叉轴 对齐(单行) | stretch / center / flex-start / flex-end |
align-content | 多行之间的交叉轴对齐 | stretch / center / flex-start / space-between |
gap | 子项间距 | <length> 或百分比 |
子项属性(写在直接子元素上):
| 属性 | 作用 | 常见值 |
|---|---|---|
flex-grow | 主轴剩余空间分配比例 | 0(默认不抢)/ >= 0 |
flex-shrink | 空间不够时的收缩比例 | 1(默认收缩)/ >= 0 |
flex-basis | 弹性生效前的初始尺寸 | auto(默认)/ <length> / 0 |
flex | grow / shrink / basis 缩写 | flex: 1(最常见) |
order | 显示顺序(覆盖源码顺序) | 整数,默认 0 |
align-self | 覆盖容器的 align-items | 同 align-items |
主轴 / 交叉轴:90% 的困惑在这里
主轴 默认是水平(row)。交叉轴 垂直于主轴。
切换方向:flex-direction: column → 主轴变垂直,交叉轴变水平。所有 justify-content / align-items 的语义跟着换。
.row { display: flex; flex-direction: row; }
.column { display: flex; flex-direction: column; }
row:水平是主轴 →justify-content管水平,align-items管垂直column:垂直是主轴 →justify-content管垂直,align-items管水平
justify-content 永远管主轴,align-items 永远管交叉轴——和方向无关。记不住就在脑子里默念这条规则。
flex 缩写的真实含义
最常用的写法是 flex: 1,但很多人不知道它展开后是什么:
.item { flex: 1; } /* = flex: 1 1 0% — 抢剩余空间,平分 */
.item { flex: auto; } /* = flex: 1 1 auto — 按内容大小伸缩 */
.item { flex: none; } /* = flex: 0 0 auto — 完全固定尺寸 */
.item { flex: 0 1 auto; } /* = flex: initial — 默认行为 */
flex-grow 计算公式
剩余空间按 grow 比例瓜分:
flex-shrink 计算公式
超额空间按 width × shrink 比例分摊:
弹性盒子中元素的总长度肯定不能超过盒子的长度,但可以小于盒子的长度。grow 默认是 0(不主动抢剩余空间),shrink 默认是 1(按比例压缩避免溢出)。
flex: 1 是布局主力 —— "抢剩余空间,平分"。三栏等宽布局就是每个 .col { flex: 1 }。
注意坑:flex: 1 在标准里是 1 1 0%,不是 1 1 0。0 和 0% 在 flex 上有微妙差别(涉及 min-content 计算),多数情况下看不出区别,但极端场景下会触发不同行为。
gap:现代间距写法
传统写法用 margin:
.item + .item { margin-left: 16px; } /* 老写法:要选第一个 */
.item:not(:last-child) { margin-right: 16px; }
现代写法直接 gap:
.container { display: flex; gap: 16px; } /* 一行搞定 */
gap 在 2021 年所有浏览器都支持,比 margin 干净一个量级。Flex、Grid、多列布局通用。


