CSS Grid 网格布局:二维排版与自适应设计
什么是 CSS Grid?
CSS Grid Layout(网格布局)是 CSS 中第一个真正为创建二维布局而生的模块。你可以同时控制元素在行和列上的摆放,轻松实现过去需要浮动、定位或 Flexbox 组合才能完成的复杂排版。
- 二维能力:Flexbox 是一维布局,擅长在单行或单列中分配空间;Grid 则是行和列同时工作。
- 容器-项目模型:将一个元素设为网格容器(grid container),其直接子元素自动成为网格项目(grid items)。
- 精确控制:通过线条编号、区域命名或轨道尺寸函数,能直观地定义每个元素的占位和尺寸。
快速上手
创建第一个网格
给父元素设置 display: grid,子元素会按默认方式排布,但这时还没有可见效果。你需要用 grid-template-columns 和 grid-template-rows 定义轨道。
.container {
display: grid;
grid-template-columns: 200px 1fr 1fr;
grid-template-rows: 100px auto;
gap: 16px;
}
200px 1fr 1fr表示三列:第一列固定 200px,后两列按 1:1 瓜分剩余空间。grid-template-rows定义行高,auto表示高度由内容撑开。gap(或grid-gap)同时设置行与列之间的间距。
fr 单位:分数单位,代表可用空间的比例。
1fr 2fr会让第二列是第一列宽度的两倍。
网格容器核心属性
定义轨道尺寸
| 属性 | 说明 | 常用写法示例 |
|---|---|---|
grid-template-columns |
定义列宽序列 | repeat(3, 1fr) 创建三等分列 |
grid-template-rows |
定义行高序列 | min-content 1fr auto |
grid-auto-rows / grid-auto-columns |
隐式网格的轨道尺寸(当项目超出显式定义的行列数) | grid-auto-rows: 150px |
repeat() 函数
避免重复书写,尤其适合多列等宽布局。
grid-template-columns: repeat(4, 120px);
/* 等价于 120px 120px 120px 120px */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
/* 自适应列数,每列最小250px,剩余空间均分 */
minmax()
限制轨道的最小和最大尺寸,是实现无媒体查询响应式的利器。
grid-template-columns: 1fr minmax(300px, 2fr) 1fr;
/* 中间列至少300px,最多占2份剩余空间 */
命名网格区域
用 grid-template-areas 可以直接用名字“画”出布局,十分直观。
.container {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
每个子元素通过 grid-area 对应区域名,自动放置到相应位置。
对齐方式
网格容器提供了强大的对齐系统,与 Flexbox 类似但分为两组:
- 项目对齐(所有网格项目在自身单元格内的对齐):
justify-items:水平方向(start / end / center / stretch)align-items:垂直方向(start / end / center / stretch)
- 轨道对齐(整个网格在容器内的对齐,当网格总尺寸小于容器的尺寸时生效):
justify-content:水平分布(start / end / center / space-between / space-around / space-evenly)align-content:垂直分布
.container {
justify-items: center;
align-items: end;
justify-content: center;
align-content: start;
}
网格项目属性
每个网格项目可以独立控制自己的位置和跨越行为。
基于线条的放置
通过 grid-column-start, grid-column-end, grid-row-start, grid-row-end (或简写 grid-column / grid-row)指定项目从哪条网格线到哪条网格线。
- 网格线条编号从 1 开始。
- 可以使用负值,如
-1代表最后一条线。
.item {
grid-column: 1 / 3; /* 从第1条线到第3条线,跨越两列 */
grid-row: 2 / span 2; /* 从第2条线开始,跨越2行 */
}
项目自身的对齐
justify-self 和 align-self 覆盖容器设置的 *-items 值,只对当前项目生效。
.item-special {
justify-self: start;
align-self: center;
}
隐式网格与自动放置
当你定义的显式行或列不够容纳所有项目时,Grid 会自动创建“隐式网格轨道”。其尺寸由 grid-auto-rows 和 grid-auto-columns 控制,位置由自动放置算法决定。
.container {
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 80px;
grid-auto-rows: 120px; /* 多余行的高度 */
}
如果希望自动放置的顺序按密集模式填充,可以使用 grid-auto-flow: dense,这会尽量填满因大小不同而产生的空隙。
响应式设计:告别媒体查询
Grid 的 auto-fill / auto-fit 与 minmax() 组合,能直接创建自适应的列布局,无需为不同的屏幕宽度编写 @media。
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
- auto-fill:当空间足够容纳新列时就创建新列,即使没有项目也会保留空的轨道。
- auto-fit:与 auto-fill 类似,但会将空轨道折叠,让有项目的轨道拉伸填满容器。通常用于希望卡片居中或填满整个宽度的场景。
.centered-cards {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
如果想要完全控制响应式断点,可以结合 minmax(0, 1fr) 和栅格区域重定义。Grid 的灵活性让媒体查询变得可选而非必须。
常见布局实现
经典圣杯布局
.holy-grail {
display: grid;
grid-template-rows: auto 1fr auto;
grid-template-columns: 200px 1fr 200px;
min-height: 100vh;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
}
动态卡片网格
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 24px;
}
.card {
display: grid;
grid-template-rows: subgrid; /* 需要父级设置 grid-template-rows 定义行维度 */
}
subgrid(较新属性):让子网格继承父网格的行或列轨道,实现项目内部对齐更一致。使用时需检查浏览器兼容性覆盖情况。
堆叠与叠加
利用同一网格区域放置多个项目,实现重叠效果(例如文本叠在图片上)。
.banner {
display: grid;
grid-template-areas: "stack";
}
.banner img, .banner .text {
grid-area: stack;
}
.text {
z-index: 1;
align-self: end;
}
Grid 与 Flexbox 如何选择?
| 场景 | 推荐 |
|---|---|
| 一维排列(单行或单列) | Flexbox |
| 二维布局(行与列同时控制) | Grid |
| 组件内部的对齐(如导航栏) | Flexbox |
| 页面级宏观布局 | Grid |
| 内容先行、尺寸未知的动态流 | Flexbox 或 Grid 的 auto-fill |
| 需要固定结构、严格对齐 | Grid |
两者不是替代关系,而是互补的。你完全可以在 Grid 容器内部嵌套 Flexbox 组件,实现最灵活的布局效果。
浏览器兼容性
CSS Grid 已获得所有现代浏览器的广泛支持(包括 IE 11 的旧版语法,不过现代开发可忽略)。在需要兼容极老旧环境时,可提供 @supports 渐进增强。
.grid-layout {
display: block; /* 降级方案 */
}
@supports (display: grid) {
.grid-layout {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}
总结
- Grid 是二维布局的终极工具,用
grid-template-columns/rows定义轨道,用gap控制间距。 - 命名区域让代码结构清晰,
fr单位和minmax()让尺寸分配灵活。 auto-fill/auto-fit与minmax()结合,无需媒体查询即可实现响应式卡片网格。- 掌握网格线的使用,可以对项目进行精确放置和跨越多行/列。
- 理解隐式网格和自动放置,能处理不确定数量的子元素。
- Grid 与 Flexbox 互相配合,是现代 CSS 布局的最佳实践。
立即动手,用 Grid 重写一个现有页面的布局,你会发现代码更少、表达力更强。