flexbox 适合一维,CSS Grid 适合二维。"侧栏 + 主内容 + 副栏"经典三栏
布局用 Grid 写比 flex 简洁 5 倍。
1. 最简版
<div class="layout">
<aside>侧栏</aside>
<main>主内容</main>
<section>副栏</section>
</div>
.layout {
display: grid;
grid-template-columns: 200px 1fr 280px;
gap: 24px;
}
fr 是"剩余空间分数"。1fr 中间吃满,左右固定。
2. 窄屏自动折叠
.layout {
display: grid;
grid-template-columns: 200px 1fr 280px;
gap: 24px;
}
@media (max-width: 1000px) {
.layout {
grid-template-columns: 200px 1fr;
}
.layout > section {
grid-column: 1 / -1; /* 副栏跨整行,垂直堆叠 */
}
}
@media (max-width: 700px) {
.layout {
grid-template-columns: 1fr;
}
}
grid-column: 1 / -1 是 Grid 的常用语法:从第 1 条线到最后一条线,
即占满全宽。
3. 命名区域(更清晰的多栏 / 多行)
.layout {
display: grid;
grid-template-columns: 200px 1fr 280px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar main rail"
"footer footer footer";
gap: 16px;
min-height: 100vh;
}
.layout > header { grid-area: header; }
.layout > aside { grid-area: sidebar; }
.layout > main { grid-area: main; }
.layout > section { grid-area: rail; }
.layout > footer { grid-area: footer; }
窄屏重排,只改 grid-template-areas:
@media (max-width: 800px) {
.layout {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"rail"
"sidebar"
"footer";
}
}
4. 12 列网格系统(不需要 Bootstrap)
.grid12 {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 20px;
}
.col-3 { grid-column: span 3; }
.col-4 { grid-column: span 4; }
.col-6 { grid-column: span 6; }
.col-12 { grid-column: span 12; }
@media (max-width: 800px) {
.col-3, .col-4, .col-6 { grid-column: span 12; }
}
<div class="grid12">
<div class="col-4">A</div>
<div class="col-4">B</div>
<div class="col-4">C</div>
<div class="col-6">D</div>
<div class="col-6">E</div>
</div>
整套不到 30 行 CSS,干掉 Bootstrap grid 一整个模块。
5. 让卡片网格自动决定列数(最常用!)
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 16px;
}
auto-fill + minmax:每列最小 260px,最大平分;窗口宽就放多列、
窗口窄就放少列,不需要任何 media query。视口超过 4×260 时一行 4 个,
缩到 2×260 时一行 2 个。
6. 让子元素拉满高度
.cards { display: grid; grid-auto-rows: 1fr; ... }
grid-auto-rows: 1fr 让每行所有 cell 等高,再加 align-self: stretch
内部内容拉满。
7. subgrid(2024 + 浏览器全支持)
子元素的 grid track 对齐父元素:
.card {
display: grid;
grid-template-rows: subgrid;
grid-row: span 3; /* 跨父网格 3 行 */
}
适合"卡片列表里每张卡片内部各自有 header / body / footer,但希望同一行
卡片的 header / body / footer 严格对齐"。
8. DevTools
Chrome / Firefox 的 Inspector 里点 grid 标记会显示 grid 线条和 area 名字,
是调试 grid 唯一有效的方法。别盲调。
踩过的坑
minmax(260px, 1fr)在窄屏(< 260px 视口)会撑破父容器;想严格防溢出
用minmax(min(260px, 100%), 1fr)。gap在 Safari 14 之前的 flexbox 不支持,Grid 支持。如果用 flex
老 Safari 兼容性差。- 用
grid-template-areas时 area 名要 每个 cell 都有 字符串。
"header . header"用.表示空。 - 大量 grid 嵌套对老设备性能不友好。深嵌套 grid 时考虑用
contain: layout
限制重排范围。
登录后参与评论。