CSS Grid 网格布局
如果说 Flexbox 是一维布局之王,那 Grid 就是二维布局之王。它一次控制"行和列"两个维度,特别适合做整页结构、卡片墙、复杂仪表盘。Flex 处理组件内部,Grid 处理整页骨架——这是目前主流的搭配。
1. 什么是 Grid?
Grid 是 CSS3 引入的二维布局模型。所谓"二维"——它同时控制行和列。给父元素加 display: grid,用 grid-template-columns 定义列,项目就会自动填进格子里。
/* 给父元素加 display: grid,直接子元素变成网格项目 */
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 三列等宽 */
grid-template-rows: auto;
gap: 16px; /* 行列间距都是 16px */
}
/* HTML 结构 */
/* <div class="gallery">
<div class="card">卡片 1</div>
<div class="card">卡片 2</div>
<div class="card">卡片 3</div>
<div class="card">卡片 4</div>
</div> */
/* 自动填进网格:前三张占第一行,第四张进第二行第一格 */Grid 的核心概念:
- 网格容器:设了
display: grid的父元素。 - 网格项目:容器的直接子元素,自动放进格子。
- 行和列:用
grid-template-rows/columns定义。 - 间距 gap:行列之间的距离,和 Flex 的 gap 一样。
2. grid-template-columns(列定义)
这是 Grid 用得最多的属性——决定网格有几列、每列多宽。
.grid {
display: grid;
gap: 16px;
/* 固定列 */
grid-template-columns: 200px 200px 200px;
/* 三列等宽(1fr = 1 份) */
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: repeat(3, 1fr);
/* 不等宽:1:2:1 */
grid-template-columns: 1fr 2fr 1fr;
/* 混合:侧栏固定,主区域自适应 */
grid-template-columns: 240px 1fr;
/* minmax:每列最小 200px,最大 1fr */
grid-template-columns: repeat(3, minmax(200px, 1fr));
}几个关键单位:
1fr(fraction):分数单位。1fr 1fr 1fr表示三列等宽;1fr 2fr表示左 1 右 2。这是 Grid 最常用的单位。repeat(n, x):重复简写。repeat(3, 1fr)等价于1fr 1fr 1fr。minmax(min, max):每列最小最大值。minmax(200px, 1fr)表示最小 200px、最大 1 份。做响应式卡片墙的关键。
3. auto-fit:自动响应式网格(超实用)
这是 Grid 最惊艳的特性——auto-fit 让列数根据容器宽度自动变化,不需要任何媒体查询。写一行,卡片墙从手机到桌面全自适应。
.grid {
display: grid;
gap: 16px;
/* auto-fit:列数随容器宽度自动变化 */
/* 每张卡片最小 200px,放得下就多排,放不下就换行 */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* 不需要媒体查询,自动响应式! */
}
/* auto-fit vs auto-fill 的区别:
auto-fit:剩余空间分给现有项目(拉伸填满)
auto-fill:保留空列(项目不拉伸)
实际项目几乎都用 auto-fit */原理:auto-fit 让浏览器自动决定列数——容器 600px 时放下 3 个 200px 的列,900px 时放下 4 个,300px 时放下 1~2 个。不需要 media query,纯 CSS 实现响应式。这是现代卡片墙的标准写法。
4. grid-template-areas:可视化布局
Grid 有个超酷的特性——可以用"命名区域"画出整个页面布局,像 ASCII 艺术一样直观。
.page {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: 60px 1fr 40px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
/* 也可以让某个项目跨多格 */
.banner {
grid-column: 1 / 3; /* 从第 1 条列线到第 3 条(跨 2 列) */
grid-row: 1 / 2; /* 占第 1 行 */
}这种写法的好处是一眼看清整页结构。改布局时,只需要重新画 areas 图——比如把 sidebar 从左挪到右,只改一行字符串即可。响应式时尤其爽:不同断点重画 areas,布局完全重排。
grid-column 和 grid-row 用线号(从 1 开始)指定项目占哪几格。1 / 3 表示从第 1 条线到第 3 条线,跨 2 格。
5. 对齐属性
Grid 的对齐比 Flex 多一倍——因为它要管"网格整体在容器里"、"项目在格子里"两个层级。
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
/* 整个网格在容器里的水平对齐 */
justify-content: center;
/* 整个网格的垂直对齐 */
align-content: start;
/* 单个网格项在格子内的水平对齐 */
justify-items: center;
/* 单个网格项在格子内的垂直对齐 */
align-items: center;
}
/* 单独给某个项目设对齐 */
.special {
justify-self: end;
align-self: start;
}- justify-content / align-content:整个网格在容器里的对齐。
- justify-items / align-items:单个项目在自己格子里的对齐。
- justify-self / align-self:单独给某个项目设。
名字和 Flex 几乎一样(justify 管水平、align 管垂直),只是层级多了。日常用得最多的是 align-items: center 让项目在格子里垂直居中。
6. Flex vs Grid:怎么选?
这是初学者最常问的问题。简单原则:
- 一维用 Flex:导航栏、按钮组、单行/单列的内容排列。项目数量可能变化、顺序重要。
- 二维用 Grid:整页骨架、卡片墙、表格化展示、表单布局。需要严格对齐行列。
- 组件内部用 Flex,组件之间用 Grid。这是目前最流行的搭配。
不是说只能选一个——它们可以嵌套使用:用 Grid 切整页(侧栏 + 主内容 + 页脚),主内容里再用 Flex 排列表格行。Grid 容器里的项目本身也可以是 Flex 容器。
7. 实战经验
- 先想结构再写 Grid:纸上画出行列,再翻译成代码。比边写边改快得多。
- 响应式卡片墙首推 auto-fit + minmax。一行搞定,不需要 media query。
- 整页布局首推 grid-template-areas。可视化、好维护、好改。
- 别小用大:做按钮组、单行对齐用 Flex 就够,别为了"统一用 Grid"而硬套。
- 子网格(subgrid):较新的特性,让嵌套的 Grid 跟父 Grid 共享网格线。现代浏览器已支持,复杂对齐时可以用。
小结
Grid 是二维布局之王。核心就两个属性:grid-template-columns 定列、gap 设间距;1fr 平分空间、auto-fit + minmax 做响应式卡片墙;grid-template-areas 可视化整页布局。和 Flex 搭配,几乎所有布局问题都能优雅解决。下一篇讲定位 position——做弹窗、吸顶导航、tooltip 的关键。
← 上一篇 CSS Flexbox 弹性布局
下一篇 CSS 定位 →