先记住这个答案
Grid 同时定义行和列,项目可以占指定的矩形区域,适合仪表盘、主内容加侧栏、需要跨行列对齐的卡片布局。Flexbox 以一个主轴排列项目,换行后每一行的弹性分配相对独立,适合导航、按钮组和卡片内部的一排操作。二者不是互斥的:外层 Grid 搭结构,内层 Flex 排局部控件很常见。
- Grid 同时定义行列轨道
- Flexbox 主要沿主轴分配空间
- Flex 换行后各行独立计算
- 页面网格与组件内 Flex 可以组合
跨行列定位时 Grid 更清楚
一个仪表盘里左侧统计卡跨两行,右侧是两张小卡。用 Flexbox 可以通过嵌套容器拼出来,但每多一层就多一套尺寸分配关系;Grid 可直接写出两列两行和左侧跨行的位置。
.dashboard { display: grid; grid-template-columns: 2fr 1fr; grid-template-rows: auto auto; gap: 16px; }
.summary { grid-row: 1 / 3; grid-column: 1; }
.metric-a { grid-row: 1; grid-column: 2; }
.metric-b { grid-row: 2; grid-column: 2; }左侧卡片覆盖两条行轨道,右侧两张卡分别落入两行。各项目的位置由共同的轨道系统确定;如果右侧内容增高,相关轨道变化仍能被整个网格感知。 Grid 并不意味着每个子组件内部也要用 Grid。摘要卡里的图标和数字只需水平排开,用 Flexbox 更易表达。
Flex 换行不等于二维网格
商品列表写 display: flex 再加 flex-wrap: wrap,项目会排成多行,但每一行独立分配剩余空间。最后一行只有两张卡时,它们可能被拉得比前几行宽;相邻行的列边界也不一定严格对齐。
如果需求是每列边界始终一致,用 Grid 的列轨道;如果需求只是允许项目自然换行,Flexbox 足够。布局系统取决于对齐规则,不能只看截图里是不是形成了“几行几列”。
一个容易混淆的例子是标签云:它看起来有几行,却不要求第二行的第一个标签与第一行严格同宽对齐,Flex 换行就很自然。价格表则不同,每行的“名称、价格、操作”必须共享列边界,Grid 更合适。先问“不同的行之间需不需要同一条列线”,通常比问“有几行”更快选出布局方式。
容易答错的地方
- 以为 Flex 换行就有共享列轨道
- Flex 行之间不共享网格列线。某行项目数量或内容变化后,列宽可能与其他行不同。
- 以为 Grid 不能灵活分配剩余空间
fr、minmax()、自动轨道和对齐属性都能处理弹性尺寸,Grid 不是固定像素布局。
面试官还会怎么问?
导航栏该用哪个?
一排导航需要沿主轴排列和留空,Flexbox 通常更直接;若要严格对齐多列内容,再考虑 Grid。
Grid 内部能放 Flex 容器吗?
能。Grid 负责组件在页面中的区域,Flex 负责组件内部按钮和文字的排列,两层职责很清楚。
卡片最后一行只有一张,还要等宽怎么办?
用 Grid 的固定列轨道或 auto-fill 策略,卡片只占一列;不要让单个 Flex 项目因剩余空间被意外拉满。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。