Grid网格布局深度解析
CSS Grid 二维布局:用 grid-template 先画"格子"再用 grid-area 放内容, fr/minmax/auto-fit 让响应式网格一行搞定,是页面级框架布局的首选。
一句话概括
Grid 是 CSS 里唯一真正的二维布局系统:同时控制行和列。Flex 是一维(一条线),Grid 是二维(一张网)——这正是它适合页面框架、仪表盘、表格的原因。
面试价值很高:Grid vs Flex 的选择是高频题;grid-template-areas 画地图式布局、auto-fit 自适应网格都是能拉开差距的亮点。
核心思路转变:从 Flex 的”排元素”变成 Grid 的”先画格子、再填内容“。最佳实践组合是——Grid 搭页面框架,Flex 排组件内部。
核心知识点
1. 核心概念:线 / 轨道 / 单元格 / 区域
- Grid Container:设了
display: grid的元素。 - Grid Line(网格线):分隔线,从 1 开始编号(N 列就有 N+1 条列线)。
- Grid Track(轨道):两条相邻线之间的行或列。
- Grid Cell(单元格):一个行轨道 × 一个列轨道。
- Grid Area(区域):任意矩形区域(可跨多格)。
2. 定义网格:grid-template + fr + minmax + repeat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div class="demo">
<div class="g fixed">100px</div><div class="g fixed">200px</div><div class="g grow">1fr</div>
<div class="g">1/3</div><div class="g">1/3</div><div class="g">1/3</div>
<div class="g">auto-fill 自适应</div><div class="g">自适应</div><div class="g">自适应</div>
</div>
<style>
.demo {
display: grid; gap: 8px; font-family: sans-serif; margin-bottom: 8px;
grid-template-columns: 100px 200px 1fr;
}
.g { background: #3498db; color: #fff; padding: 16px 8px; text-align: center; border-radius: 6px; font-size: 13px; }
</style>
<!-- 自适应版本:容器变窄自动减列 -->
<div class="demo auto">
<div class="g">卡片</div><div class="g">卡片</div><div class="g">卡片</div><div class="g">卡片</div>
</div>
<style>
.demo.auto { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
</style>
fr:剩余空间的一份。先算完所有固定列/内容列,再把”剩下的”按fr比例分配。minmax(100px, 1fr):最小 100px,最大吃满剩余空间。repeat(auto-fit, minmax(150px, 1fr)):列数随容器宽度自动增减(响应式网格一行搞定)。auto-fillvsauto-fit:auto-fill尽可能多建轨道(容器宽但项目少时右侧留空位);auto-fit会折叠空轨道,让已有项目拉伸填满——要做”项目少也铺满”用auto-fit。
3. 模板布局:grid-template-areas 画地图
用”画地图”的方式在 CSS 里声明布局,HTML 结构完全不用改:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div class="page">
<header>Header</header>
<nav>Nav</nav>
<main>Main</main>
<aside>Aside</aside>
<footer>Footer</footer>
</div>
<style>
.page {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 80px 1fr 60px;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
gap: 10px; min-height: 360px;
}
header { grid-area: header; background: #e74c3c; }
nav { grid-area: nav; background: #3498db; }
main { grid-area: main; background: #2ecc71; }
aside { grid-area: aside; background: #f39c12; }
footer { grid-area: footer; background: #9b59b6; }
.page > * { display: flex; align-items: center; justify-content: center; color: #fff; border-radius: 6px; }
</style>
- 地图里每个名字对应一个
grid-area;.表示那个单元格【故意留空】,不属于任何区域。 - 响应式只需换一套
grid-template-areas(比如手机变单列),HTML 一行不动——布局与结构解耦。
4. 网格线放置与 span
不写名字,直接用线编号精确摆放,或用 span 跨格:
1
2
3
4
5
.item {
grid-column: 1 / 3; /* 从第 1 条列线到第 3 条,占 2 列 */
grid-row: 1 / -1; /* -1 = 最后一条线,占满所有行 */
grid-column: 2 / span 3; /* 从第 2 线起跨 3 列 */
}
5. 隐式网格:grid-auto-rows / grid-auto-columns
当项目超出显式定义的轨道,Grid 会自动创建隐式轨道:
1
2
3
4
.container {
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 80px; /* 自动生成的行,高 80px */
}
6. 对齐:justify/align items vs content
常和 Flex 搞混,关键看”作用对象”:
| 作用对象 | 水平 | 垂直 |
|---|---|---|
| 单元格内的项目 | justify-items | align-items |
| 整个网格在容器内 | justify-content | align-content |
只有轨道总尺寸小于容器时,justify-content / align-content 才看得出效果。
其实你每天都在用
- 后台仪表盘(header/sidebar/main/footer) →
grid-template-areas一张地图搞定。 - 卡片墙自动按宽度换行且等宽 →
repeat(auto-fit, minmax(200px, 1fr))。 - 三栏 / 两栏页面框架 → 显式
grid-template-columns。 - 图片画廊不规则拼接 →
grid-column/grid-row跨线。 - 表单”标签 + 输入框”两列对齐 → Grid 比 Flex 更直观。
- 响应式重排(手机变单列) → 只改
grid-template-areas。
常见误解(FAQ)
❌ 误区一:”Grid 比 Flex 更先进,应该全都用 Grid”
错。Flex 适合一维(导航、标签、一组按钮),Grid 适合二维(页面框架、表格、仪表盘)。真实项目是”Grid 搭框架 + Flex 排组件”混用,不是二选一。
❌ 误区二:”auto-fill 和 auto-fit 没区别”
有。auto-fill 保留空轨道(容器宽、项目少时右侧留空);auto-fit 折叠空轨道,让已有项目拉伸填满。要”项目少也铺满”用 auto-fit。
❌ 误区三:”grid-template-areas 里的 . 是占位内容”
. 表示那个单元格【故意留空】,不属于任何命名区域。它是”此地无银”的语义,不是装饰。
❌ 误区四:”fr 单位跟 % 差不多”
不同。% 直接按容器比例定宽;fr 是在扣除所有固定列 / 内容列之后,对【剩余空间】按比例分配。混合布局里 fr 比 % 更符合直觉。
❌ 误区五:”justify-items 和 justify-content 分不清”
记住作用对象:items 管”每个项目在它自己格子里怎么摆”,content 管”整张网格在容器里怎么摆”。容器比网格大时才看得出 content 的效果。
一句话总结
Grid 把布局从”嵌套 div 地狱”变成”画一张格子地图”:先 grid-template 定行列、fr/minmax 分弹性、grid-area 填内容,页面框架这件事从此有章法、可维护、好响应。