Grid 网格布局实战:快速实现复杂网页排版
Grid 布局是 CSS 中最强大的二维布局系统。相比 Flex 的单向控制,Grid 能同时处理行和列,让复杂排版从" hack 堆砌"变成"声明式描述"。
一、为什么选 Grid,而不是 Flex?
| 场景 | Flex | Grid |
|---|---|---|
| 导航栏横向排列 | ✅ 擅长 | 可用但多余 |
| 卡片自适应行列 | ⚠️ 需媒体查询配合 | ✅ 一行代码搞定 |
| 整体页面框架(header+main+sidebar+footer) | ❌ 勉强 | ✅ 天生为此设计 |
| 指定某个元素跨 N 行 N 列 | ❌ 做不到 | ✅ grid-row: span 2 |
结论:Flex 管"一条线",Grid 管"一整面"。
二、核心语法:6 个属性够用了
css
css
1.container {
2 display: grid;
3 grid-template-columns: 200px 1fr 200px; /* 三列:固定 | 自适应 | 固定 */
4 grid-template-rows: 60px 1fr 40px; /* 三行:固定 | 自适应 | 固定 */
5 gap: 16px; /* 统一间距 */
6}
7
6 个关键属性速查
| 属性 | 作用 | 高频值 |
|---|---|---|
grid-template-columns |
定义列 | 1fr 1fr 1fr / repeat(3, 1fr) |
grid-template-rows |
定义行 | auto 1fr auto |
gap |
间距 | 16px / 1rem |
grid-column |
跨列 | span 2 |
grid-row |
跨行 | span 3 |
grid-area |
命名区域 | header / main / sidebar |
三、实战:3 个真实排版方案
方案 A:经典后台管理布局(10行代码)
css
css
1.layout {
2 display: grid;
3 height: 100vh;
4 grid-template-areas:
5 "header header header"
6 "sidebar main main"
7 "footer footer footer";
8 grid-template-columns: 240px 1fr;
9 grid-template-rows: 60px 1fr 40px;
10}
11
12.header { grid-area: header; }
13.sidebar { grid-area: sidebar; }
14.main { grid-area: main; }
15.footer { grid-area: footer; }
16
效果: 左侧固定侧边栏 + 顶部导航 + 底部信息栏,main 区自适应剩余空间。
方案 B:响应式卡片列表(自适应行列,零媒体查询)
css
css
1.card-grid {
2 display: grid;
3 grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
4 gap: 20px;
5}
6
原理:
auto-fit:自动填充尽可能多的列minmax(280px, 1fr):每列最小 280px,超出部分均分- 不需要任何媒体查询,浏览器自动计算
4 列宽屏 → 2 列平板 → 1 列手机,全自动。
方案 C:杂志风不对称布局
css
css
1.magazine {
2 display: grid;
3 grid-template-columns: 1fr 1fr 1fr 1fr;
4 grid-template-rows: auto auto auto;
5 gap: 12px;
6}
7
8.featured {
9 grid-column: span 2; /* 占两列 */
10 grid-row: span 2; /* 占两行 */
11}
12
13.side-item {
14 grid-column: span 1;
15 grid-row: span 1;
16}
17
效果: 头条大图占 2×2 区域,其余小卡片自动填充剩余格子。
四、Grid vs Flex:什么时候混用?
最强组合是 Grid 框架 + Flex 内部:
css
css
1/* Grid 控制整体分区 */
2.page {
3 display: grid;
4 grid-template-columns: 250px 1fr;
5}
6
7/* Flex 控制分区内部对齐 */
8.sidebar-nav {
9 display: flex;
10 flex-direction: column; /* 导航项纵向排列 */
11 gap: 8px;
12}
13
五、避坑清单
| 坑 | 正确做法 |
|---|---|
fr 单位和 px 混用导致溢出 |
优先用 fr 做弹性,minmax() 兜底 |
以为 gap 兼容所有浏览器 |
IE 不支持,需用 margin 降级 |
过度依赖 grid-template-areas |
命名区域可读性好,但调试时不如行列号直观 |
在 Grid 容器内还用 float |
直接删掉,Grid 完全替代 float 布局 |
六、一句话总结
Flex 解决"一排怎么摆",Grid 解决"一整页怎么摆"。 遇到任何需要行列同时控制的场景,先写
display: grid,90% 的问题一行解决。