刚开始学 CSS 时,最常纠结的问题是:这里到底该用 Grid 还是 Flexbox? 其实有一个非常好记的判断标准。
一维排布用 Flex,二维排布用 Grid。也就是说:只关心一个方向(一行或一列)用 Flex;同时要控制行和列,用 Grid。
Flexbox:内容驱动的单方向布局
适合导航栏、按钮组、卡片内部的「图标 + 文字」这类场景。
.nav {
display: flex;
align-items: center; /* 垂直居中 */
justify-content: space-between;
gap: 16px; /* 用 gap 代替 margin,省心很多 */
}
/* 让中间区域自动占满剩余空间 */
.nav .spacer { flex: 1 1 auto; }
记住三个属性就能覆盖大部分需求:display: flex 开启布局,
gap 控制间距,flex: 1 让元素按比例分配剩余空间。
Grid:结构驱动的二维布局
页面整体框架、卡片列表、图片墙,用 Grid 会舒服很多。
/* 自适应卡片网格:一行能放几张就放几张 */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
/* 页面主框架 */
.layout {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-areas: "sidebar main";
}
@media (max-width: 720px) {
.layout {
grid-template-columns: 1fr;
grid-template-areas: "main" "sidebar";
}
}
上面这段 repeat(auto-fill, minmax(280px, 1fr)) 是我最常用的写法,
一行代码就实现了「响应式 + 自动换行」,不需要写任何媒体查询。
两个一起用才是常态
真实项目里,两者通常是嵌套使用的:外层用 Grid 划分区域,内层用 Flex 排列内容。
<article class="card"> <!-- 外层:Grid 决定卡片位置 -->
<header class="card-head"> <!-- 内层:Flex 排列图标与标题 -->
<span class="icon"></span>
<h3>标题</h3>
</header>
</article>
速查表
| 需求 | 推荐方案 |
|---|---|
| 导航栏左右分布 | Flexbox |
| 图标与文字垂直居中 | Flexbox |
| 卡片列表自适应换行 | Grid |
| 侧边栏 + 主内容区 | Grid |
| 图片墙 / 瀑布流 | Grid |
| 按钮组、标签组 | Flexbox |
几个容易忽略的细节
- 用
gap而不是给子元素加 margin,能避免最后一个元素的间距问题。 - Flex 子项默认不收缩由内容撑开的宽度,文字溢出时记得加
min-width: 0。 - Grid 的
fr单位代表剩余空间比例,比百分比更好用。 - 布局问题优先怀疑容器是否设置了
display,而不是先怀疑子元素。
如果只记一句话:先在纸上画格子,再决定用什么。 布局是结构问题,不是属性记忆问题。