Flex专管一维排列(行或列),适合内容对齐与伸缩;Grid专管二维网格,适合行列交叉布局。项目中应Grid定骨架、Flex调细节,避免滥用。

Flex 是“排队”,Grid 是“画格子”
Flex 布局只管一个方向:要么横着排(flex-direction: row),要么竖着排(flex-direction: column)。它适合解决「内容怎么在一条线上对齐、换行、伸缩」的问题。比如导航栏里几个 水平铺开,或表单里标签和输入框垂直对齐——用 Flex,两行 CSS 就搞定。
Grid 布局则直接定义行和列,像在容器里先画好一张带横线和竖线的表格,再把元素填进指定格子。它天然支持跨行、跨列、区域命名(grid-template-areas)、行列比例控制(1fr / minmax())等二维操作。页面级骨架、仪表盘分区、响应式卡片网格,都是 Grid 的主场。
常见错误现象:
– 用多层 display: flex 嵌套模拟三栏布局,结果每层都要写 flex-basis + 媒体查询,维护成本飙升;
– 给纯水平导航加 display: grid,只为用 justify-content: center,反而要额外处理 gap 兼容性(Safari 14.0 之前有偏移)。
什么时候必须用 Grid?
当布局出现明确的「行列交叉关系」,且无法靠单方向伸缩解决时,Grid 就不是可选项,而是唯一合理解:
立即学习“前端免费学习笔记(深入)”;
- 页头 + 左侧菜单 + 主内容 + 页脚这种经典四区结构 → 用
grid-template-areas一行定义视觉顺序,HTML 结构不用为样式妥协 - 商品卡片列表要求「每行固定 3 列、高度自动拉平、宽度随容器响应变化」→
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)),无需 JS 或媒体查询 - 需要某个按钮跨两行、某个标题跨三列 → 直接写
grid-row: 1 / 3和grid-column: 2 / 5,Flex 做不到
注意:auto-fit 和 minmax() 在 IE11 完全不支持;若需兼容,得退回固定列数 + 媒体查询方案。
什么时候坚持用 Flex?
只要任务是「让一堆东西排成一串,并对齐/分隔/居中」,Flex 就更轻、更稳、更兼容:
- 导航链接水平均匀分布 →
justify-content: space-between - 按钮组内图标+文字垂直居中 →
align-items: center - 卡片内部标题、描述、操作按钮上下堆叠并底部对齐 →
flex-direction: column+margin-top: auto - 响应式卡片流(允许换行)→
flex-wrap: wrap+gap,iOS 14.5+ 即稳定,比 Grid 的 gap 兼容性早半年
性能影响很小,但语义清晰:Flex 不会去“规划网格”,它只响应内容尺寸变化。滥用 Grid 做一维事,反而增加渲染负担(尤其旧版 Safari 对 gap 的重绘 bug)。
真实项目里怎么混用?
90% 的合理布局都是 Grid 定骨架 + Flex 调细节:
-
.dashboard用 Grid 划出「筛选栏」「图表区」「指标卡区」三大块;每个「指标卡」内部用 Flex 居中图标、数值和单位 -
.gallery用 Grid 控制列数和间距;每张.card用 Flex 垂直居中标题与操作按钮(align-items: center+justify-content: space-between) - 避免反模式:Grid 容器里的子项又设
display: grid—— 除非真需要嵌套二维控制(如某张卡片内还要做 2×2 小图标网格),否则大概率是分层没想清楚
容易被忽略的一点:Grid 的 align-items 和 Flex 的 align-items 表面同名,实际作用对象不同——前者控制所有子项在各自单元格内的交叉轴对齐,后者控制子项在 Flex 容器交叉轴上的整体对齐。混用时别想当然套用同一套逻辑。










