约 8 分钟读完 · 更新于 2026-10-21 · 文中每条都能在下面的配套工具里动手验证
坑 1–3:轴与换行
- flex-direction 换轴后对齐「反转」:column 方向主轴是垂直的,justify-content 变成控制垂直、align-items 控制水平。不是属性坏了,是轴变了。口诀:justify 永远管主轴,align 永远管交叉轴。
- 默认不换行:flex-wrap 默认 nowrap,子项宁 可压缩也不换行。要换行必须显式写 flex-wrap: wrap,且换行后 align-content 才开始起作用(控制「行与行」的间距分布,align-items 只管单行内)。
- margin: auto 失灵:Flex 子项的 auto margin 平分的是「主轴剩余空间」,它优先于 justify-content。想在两枚子项之间留白,给中间元素 margin-left: auto 比改容器对齐更直接。
坑 4–6:伸缩三兄弟 flex: 1 背后发生了什么
flex 是 flex-grow、flex-shrink、flex-basis 的缩写。flex: 1 等于 1 1 0%——完全按剩余空间分配、忽略内容宽度;flex: auto 等于 1 1 auto——先按内容宽度,再分剩余空间。两者的差异是「内容不同的卡片宽度不齐」的头号原因。
等宽三栏:用 flex: 1(basis 0).col { flex: 1; } /* = 1 1 0%,三栏严格等宽,与内容长短无关 */
内容优先:用 flex: auto.col { flex: auto; } /* = 1 1 auto,先保内容再分剩余,内容不同宽度不同 */
- 内容被压扁:flex-shrink 默认 1,空间不足时按比例压缩子项。文字按钮被压出省略号、图标被挤变形,都是它。不想被压的子项写 flex-shrink: 0。
- flex-basis 和 width 谁说了算:flex-basis 优先于 width(除非 basis 是 auto)。子项同时写了 width 和 flex: 1 时,width 实际失效——「width 写了没反应」多半是这个原因。
坑 7–8:间距与溢出
- gap 与 margin 的取舍:gap 只作用于子项之间(首尾无多余间距),是现代首选;margin 要自己处理首尾去边。gap 在 Flex 里的兼容性 2021 年起已全面可用,老项目维护除外。
- min-width: auto 撑爆容器:Flex 子项的默认最小尺寸是「内容最小宽度」——长单词、长 URL、不换行的表格会把子项撑到超出容器。修复:子项加 min-width: 0(或 overflow: hidden)。这是「Flex 子项溢出但 max-width 没用」的元凶。
长内容撑爆的修复.flex-child {
min-width: 0; /* 允许收缩到内容以下 */
overflow-wrap: anywhere;
}
坑 9–10:对齐与高度
- stretch 把子项拉成等高:align-items 默认 stretch,子项会被拉满容器高。想让子项保持内容高度就写 align-items: flex-start;想要等高卡片反而要利用 stretch——「卡片高度不齐」有时是有人显式改掉了它。
- 百分比高度失效:父容器没有确定高度时,子项 height: 100% 解析为 auto。Flex 里更稳的做法是让容器 stretch 或给子项 align-self: stretch,而不是赌百分比。
一张速查表:症状 → 属性
| 想要的效果 | 写法 | 常见错写 |
| 子项之间等距 | gap: 12px 或 justify-content: space-between | 给每个子项加 margin-right(尾多余) |
| 某子项贴右 | 该子项 margin-left: auto | 容器 justify-content: flex-end(全体右移) |
| 子项不被压缩 | flex-shrink: 0 | 只调 flex-grow(grow 管放大不管压缩) |
| 允许换行 | flex-wrap: wrap | 以为子项总宽度超了自然换行 |
| 垂直居中(column 时) | justify-content: center | align-items: center(那是水平) |
| 子项可内部滚动 | min-width: 0 + overflow: auto | 只写 overflow: auto(被 min-width:auto 顶住) |
常见问题
flex: 1 和 flex: auto 到底差在哪?
flex: 1 的 basis 是 0%,分配只看剩余空间,子项等宽;flex: auto 的 basis 是 auto,先保留内容宽度再分剩余,内容不同宽度就不同。要严格等宽用 flex: 1。
gap 在 Flex 里兼容性可以放心用吗?
Chrome 84+、Firefox 63+、Safari 14.1+ 起全面支持,2021 年之后的现代浏览器环境可以放心作为首选;需要兼容更老的内嵌 WebView 时再退回 margin 方案。
子项里长单词把布局撑爆怎么办?
给该子项 min-width: 0 允许收缩到内容以下,再配合 overflow-wrap: anywhere 或 overflow: hidden 让内容换行/裁剪。根因是 Flex 子项默认最小宽度等于内容宽度。