「Grid 还是 Flexbox」这个问题没有标准答案,但有判断依据:看你要控制的是一个方向,还是行列同时对齐。下面用三个最常见的布局场景说明。

先分清一维与二维
- 一维:一行按钮、一个导航条、卡片内部的图标加文字。用 Flexbox;
- 二维:行列都要对齐,例如「左侧设置 + 右侧预览」「三列卡片、间距统一」。用 Grid;
- 页面级骨架用 Grid,组件内部用 Flexbox,是最省心的组合。
Flexbox:一行之内怎么排
导航、按钮组、列表项这类「沿一个方向排列」的场景,Flexbox 的 justify-content 与 align-items 已经够用。
.toolbar {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem;
}
.toolbar .spacer {
margin-left: auto; /* 把右侧操作推到最右 */
}
用 gap 而不是给子元素加 margin-right,换行时不会多出多余的间距。flex: 1 让搜索框占满剩余空间,比写死宽度更适应窄屏。
Grid:行列同时对齐
卡片列表最典型。用 auto-fit 加 minmax 可以写出「不写媒体查询也能自适应」的网格:
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
gap: 1.25rem;
}
minmax(16rem, 1fr) 表示每列最窄 16rem、剩余空间平均分配;容器放得下几列就排几列,放不下自动减少列数。相比固定 grid-template-columns: 1fr 1fr 1fr 再写三个断点,维护成本低很多。
左右分栏与粘性侧栏
.layout {
display: grid;
gap: 2rem;
grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 1024px) {
.layout {
grid-template-columns: minmax(0, 1fr) 18rem;
}
}
minmax(0, 1fr) 里的 0 很关键:默认的 1fr 会被内容撑开,长代码块或长链接会把右侧栏挤走。加上 minmax(0, 1fr) 才能让内容在自己的列里滚动或换行。
两个常见误区
- 用 Grid 做「一行三个等宽按钮」,然后在每个按钮内部又用 Grid 居中 —— 内部其实用
display: flex; align-items: center; justify-content: center更直观; - 用 Flexbox 硬做二维网格,靠
width: 33.33%加负边距凑间距。换成 Grid 加gap一行就够。
响应式的两种思路
一种是「容器宽度决定列数」,用 auto-fit;另一种是「断点决定布局」,用媒体查询切换 grid-template-areas。前者适合卡片流,后者适合页面骨架。
.page {
display: grid;
grid-template-areas:
"header"
"main"
"aside";
}
@media (min-width: 1024px) {
.page {
grid-template-areas:
"header header"
"main aside";
grid-template-columns: minmax(0, 1fr) 18rem;
}
}
用 grid-template-areas 的好处是布局在 CSS 里一眼能看懂,改顺序不用动 HTML。
小结
一句话选择法:只控制一个方向的间距与对齐,用 Flexbox;要同时控制行列,用 Grid;页面骨架用 Grid、局部组件用 Flexbox。真正决定可维护性的不是选哪个,而是统一 gap 与容器宽度,避免每个组件各写一套边距。布局改完记得在窄屏实测,图片与字体的加载优化可以接着看前端性能清单。