结论是“grid管页面骨架,flexbox管组件内对齐”。grid用于语义区域布局(如header/main/sidebar),支持跨行跨列与响应式区域重排;flexbox适合一维流式排列(如导航栏、卡片内容),在动态内容和高度不均场景更自然。

Grid 负责页面骨架,Flexbox 负责组件内对齐
直接说结论:不是“选哪个”,而是“谁管哪层”。display: grid 应该用于定义语义区域(如 header、main、sidebar),而 display: flex 适合在这些区域内做一维排列(比如导航栏里 logo + nav + search 水平排布,或卡片里图片+文字+按钮垂直堆叠)。
常见错误是用 Flexbox 去撑起整页结构——比如写 display: flex; flex-direction: column; 包住所有区块,再靠 flex: 1 让 main 自适应高度。这看似能用,但一旦要响应式重排(比如手机端把 sidebar 收进 drawer),就得靠 order + display: none + 多层 wrapper 拼凑,DOM 和样式迅速失控。
- Grid 容器子项上写
justify-content无效(它只认justify-items或justify-self) - Flex 容器子项上写
grid-column浏览器直接忽略 - Grid 内部子元素再设
display: flex完全合法,且推荐这么做
需要跨行跨列或区域重排时,必须用 Grid
比如某张数据卡片要横跨两列、纵跨三行,或者桌面端五区布局("header header header" "sidebar main aside" "footer footer footer")到手机端一键切为单列("header" "main" "footer"),只有 grid-template-areas 能干净实现。
Flexbox 没有行列坐标系,强行模拟会导致:
- 嵌套超过两层 flex 容器后,Chrome DevTools Layout 树深度翻倍,调试困难
- 用
flex-wrap+flex-basis控制多列时,子项高度不一致会引发错行(第二列首项被挤到第三行) -
order只改视觉顺序,不改变物理位置,无法真正“跳过”某一行
实操建议:grid-template-columns: repeat(2, 1fr) 比 repeat(auto-fit, minmax(250px, 1fr))) 更稳,尤其在旧款安卓 WebView 或低端 iOS 设备上,后者 resize 时 Layout 耗时可能翻倍。
Flexbox 更适合动态内容和一维流式场景
当项目数量不确定、内容高度不均、或需快速响应增删时,Flexbox 是更自然的选择。比如导航菜单新增一项,无需改 CSS;表单控件左右配对(label + input),align-items: center 一行搞定;媒体对象(头像+文字)用 flex: 0 0 100px + flex: 1 即可。
注意两个典型陷阱:
-
height: 100%在 flex 子项里常失效——父容器没显式高度,继承链就断了;改用min-height: 0或给父级加height才能触发 -
align-content对单行 flex 容器无效,容易误以为没生效;多行才起作用
另外,flex: 1 实际是 flex: 1 1 0% 的简写,基准值为 0,这点在 IE11 中表现特殊,生产环境需留意。
gap 优先于 margin,但要注意 Safari 兼容性
gap 是 Grid 和 Flexbox 都支持的现代间距方案,它不参与盒模型计算,无塌陷风险,也不用写 margin: -Xpx 抵消。但 Safari 14.1 之前对 gap 支持不稳定,若需兼容更老版本,得降级用 margin + first-child/last-child 排除。
Grid 还有个易忽略点:grid-auto-rows: minmax(100px, auto) 能防内容为空时网格塌陷;而 Flexbox 没对应机制,只能靠 min-height 或伪元素 hack。
最后提醒一句:别在 Grid 容器里混写 fr 和像素单位(如 1fr 200px),小屏下极易触发横向滚动,尤其在移动端。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











