align-items: stretch 是 flex 多列等高的默认行为,但需满足父容器为 flex、子项无 height/max-height 限制、父容器高度可确定或由内容撑开、min-height 不设为 0 等前提;grid 中省略 grid-template-rows 或设为 1fr 同样可实现等高,且更稳定。

flex 实现多列等高:align-items: stretch 是默认行为,但容易被忽略的约束条件
只要父容器设为 display: flex,子项在交叉轴(通常是垂直方向)上默认就会等高——前提是没显式设置 align-items 为 flex-start、center 等值。这个“拉伸”行为依赖几个隐含前提:
- 子元素不能有
height或max-height硬性限制(否则会覆盖 stretch) - 父容器需有明确高度,或至少能由内容撑开;若父容器高度为
auto且无其他约束,stretch 仍生效,但视觉上可能看不出“等高”,因为整体高度由最高列决定 - 子项的
min-height若设为0,可能破坏 stretch(旧版 Safari 有此问题,建议避免)
.container {
display: flex;
}
.item {
/* 不要写 height: 200px; */
/* 不要写 align-self: flex-start; */
}grid 实现多列等高:用 grid-template-rows: 1fr 更可控
display: grid 下,等高是天然属性,但需注意行定义方式。直接写 grid-template-rows: 1fr 会让所有行高一致,而多列布局通常只需“每行内各列等高”,此时应省略 grid-template-rows,让 Grid 自动按内容生成行,并靠 align-items: stretch(Grid 中也默认开启)拉齐:
- 若显式写了
grid-template-rows: auto,等高仍成立;但写成grid-template-rows: max-content就会失效 - 想让所有列统一按最高列等高(单行多列),推荐
grid-template-rows: 1fr;若内容跨多行,则用grid-auto-rows: 1fr - Flex 对单行布局更轻量,Grid 在复杂嵌套或响应式断点中更稳定
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
/* 不写 grid-template-rows 即可 */
}
.item {
/* 同样避免 height / min-height 干扰 */
}常见失效场景:为什么加了 flex 却不等高?
最常踩的坑不是语法错,而是布局上下文干扰:
- 父容器被设了
overflow: hidden且子项有margin-bottom,导致实际高度被截断,视觉上不等高 - 子项内部用了
display: table-cell或绝对定位元素,脱离文档流后不再参与 stretch 计算 - CSS 重置库(如 normalize.css)里某些全局
box-sizing设置不一致,造成 padding/border 计算偏差,看起来高度不同 - 使用了
vertical-align(仅对 inline/inline-block 有效),但在 flex 子项上写它完全无效,还可能误导调试方向
兼容性与选择建议:别为了兼容 IE 而放弃 flex
IE10/11 对 flex 的 align-items: stretch 支持不完整(尤其遇到 min-height 时)。如果必须兼容,可用 JS 补丁或降级为 display: table-cell;但现代项目中,优先用 flex 或 grid:
立即学习“前端免费学习笔记(深入)”;
- Flex 更适合一维布局(单行或单列),代码简洁,性能好
- Grid 更适合二维控制(比如既要等高,又要等宽,还要响应式重排),语义清晰
- 二者都能通过
@supports安全降级,例如:@supports not (display: grid) { .container { display: flex; } }
真正麻烦的不是选哪个方案,而是忘了检查子项是否悄悄加了 height 或 align-self —— 这些属性比浏览器兼容性更容易让你花两小时找 bug。










