Flexbox 还是 Grid?我的选型决策树
团队 Code Review 时又看到有人用 Flex 硬搓九宫格,一排三个换行靠 flex-wrap + 算宽度。我忍不住留了条评论:这个场景 Grid 三行代码就解决了。
这俩布局系统我都在生产环境深度用过,今天把选型经验整理成一篇。
一句话区分
- Flexbox 是一维布局:处理"一行/一列怎么排"
- Grid 是二维布局:处理"行和列同时怎么排"
这不是定义,是决策的第一原则。一维的问题用 Grid 能做但别扭,二维的问题用 Flex 能做但费劲。
先看 Flex 的主场
场景 1:导航栏、工具栏——典型的"一行东西排开":
.navbar {
display: flex;
align-items: center; /* 垂直居中 */
gap: 16px;
}
.navbar .spacer {
flex: 1; /* 把后面的项推到最右边 */
}
场景 2:内容驱动的分布——子项数量不固定、尺寸由内容决定:
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
标签云这种"有多少排多少、放不下就换行"的需求,Flex 的 flex-wrap 是天选。
场景 3:等高、居中、自适应伸缩:
.media {
display: flex;
gap: 12px;
}
.media .body {
flex: 1; /* 吃掉剩余空间 */
min-width: 0; /* 防止内容撑爆,老生常谈的坑 */
}
Flex 的关键词是内容驱动:子项多大、几个,布局跟着内容走。
再看 Grid 的主场
场景 1:页面骨架——头部、侧边栏、主区、底栏的经典布局:
.layout {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 60px 1fr auto;
grid-template-areas:
'header header'
'sidebar main'
'footer footer';
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
grid-template-areas 用 ASCII 图定义布局,一眼看懂结构,这是 Flex 永远给不了的可读性。
场景 2:整齐的卡片网格——开头说的九宫格:
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
/* 响应式版:自动填充,最小 280px */
.card-grid-auto {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
repeat(auto-fill, minmax()) 这行是 Grid 最香的模式:列数随容器宽度自动增减,不用写任何媒体查询。
场景 3:对齐要求严格的双轴布局——表单、仪表盘,行列都要对得整整齐齐的场景。
Grid 的关键词是布局驱动:先定好格子,内容往格子里填。
决策树
我自己脑内的判断流程是这样的:
要排的东西是"一行/一列"吗?
├─ 是 → 数量固定吗?
│ ├─ 固定,且要精确控制比例 → Flex
│ └─ 不固定,跟着内容走 → Flex(flex-wrap)
└─ 不是(行列都有)→ 行列结构是"布局先定"还是"内容先定"?
├─ 布局先定(页面骨架、仪表盘) → Grid
├─ 内容先定(卡片墙) → Grid 的 auto-fill
└─ 只有一行但对齐复杂 → 多半还是 Flex + gap
简单粗暴版:一排用 Flex,一片用 Grid。
组合拳才是日常
真实项目里俩是嵌着用的。一个典型的卡片:
/* Grid 负责卡片的整体排布 */
.card-wall {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 24px;
}
/* Flex 负责单张卡片内部的结构 */
.card {
display: flex;
flex-direction: column;
}
.card .content {
flex: 1; /* 内容区吃掉剩余空间,让按钮贴底 */
}
外层 Grid 管"卡片们怎么摆",内层 Flex 管"卡片内部怎么排",flex: 1 还顺手解决了卡片高度不一致时按钮对不齐的老问题。
小结
- Flex 一维、内容驱动;Grid 二维、布局驱动
- 导航/工具栏/标签流 → Flex;页面骨架/卡片网格/仪表盘 → Grid
repeat(auto-fill, minmax(280px, 1fr))是响应式网格的银弹- 真实项目是组合拳:Grid 定大局,Flex 管局部
别再纠结"哪个更强"了,它们解决的是不同维度的问题。下次写布局前先问自己:这是一维还是二维?答案基本就出来了。
看到这里了?如果这篇文章帮到过你
请我喝瓶可乐就好 🥤

评论0 条
还没有评论,来抢沙发~