引言
CSS Grid Layout(网格布局)是CSS最强大的布局系统。与Flexbox专注于一维布局不同,Grid是为二维布局而设计的——同时处理行和_column_。自2017年以来获得了所有现代浏览器的支持,它彻底改变了我们构建Web布局的方式。本指南将从基础概念出发,系统性地掌握Grid布局的每一个层面。
一、Grid基础概念
1.1 网格容器与网格项目
Grid布局涉及两个核心角色:网格容器(设置display: grid的元素)和网格项目(容器的直接子元素)。
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 100px 100px;
gap: 10px;
}
- 网格容器(Grid Container):应用display: grid的元素
- 网格项目(Grid Item):容器的直接子元素成为网格项目
- 网格线(Grid Line):网格结构中的分界线,从1开始编号
- 网格轨道(Grid Track):相邻网格线之间的空间,即行或列
- 网格单元格(Grid Cell):网格中的单个格子
- 网格区域(Grid Area):由网格线围成的矩形区域
1.2 显示网格与隐式网格
Grid包含两类网格:
- 显式网格(Explicit Grid):通过grid-template-columns和grid-template-rows明确创建的网格
- 隐式网格(Implicit Grid):当项目超出显式网格时自动创建的轨道
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 显式创建3列 */
grid-auto-rows: minmax(100px, auto); /* 隐式行自动高度 */
}
二、定义网格轨道
2.1 固定与弹性单位
Grid提供了丰富的单位来定义轨道尺寸:
| 单位 | 说明 | 示例 |
|---|---|---|
| px | 固定像素 | grid-template-columns: 200px 200px |
| fr | 弹性分数单位 | grid-template-columns: 1fr 2fr(2:1比例) |
| % | 百分比 | grid-template-columns: 25% 75% |
| auto | 内容自适应 | grid-template-columns: auto 1fr |
| minmax() | 范围限制 | grid-template-columns: minmax(200px, 1fr) |
| min-content | 最小内容宽度 | grid-template-columns: min-content 1fr |
| max-content | 最大内容宽度 | grid-template-columns: max-content 1fr |
2.2 repeat()函数与auto-fill/auto-fit
repeat()简化重复轨道的定义,结合auto-fill和auto-fit可以实现无需媒体查询的响应式网格:
/* 传统写法 */
grid-template-columns: 1fr 1fr 1fr 1fr;
/* 使用repeat() */
grid-template-columns: repeat(4, 1fr);
/* auto-fill: 尽可能创建轨道(即使空着) */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
/* auto-fit: 折叠空轨道,填充可用空间 */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
auto-fill vs auto-fit的关键区别:当项目数量少于可容纳的轨道数时,auto-fill保留空轨道占位,auto-fit则将空轨道折叠为零宽度,让已有项目扩展填满。
2.3 grid-auto-rows 与 grid-auto-columns
控制隐式创建的轨道尺寸:
.grid {
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 200px; /* 仅第一行200px高 */
grid-auto-rows: minmax(100px, auto); /* 隐式行最小100px,最大自适应 */
}
三、网格线布局
3.1 基于线的定位
每个网格线都可以通过编号引用,正数从左/上开始,负数从右/下开始:
.item {
grid-column-start: 1;
grid-column-end: 3; /* 跨越第1到第3条列线(占2列) */
grid-row-start: 1;
grid-row-end: 2; /* 在第1行 */
}
/* 简写形式 */
.item {
grid-column: 1 / 3;
grid-row: 1 / 2;
}
/* 使用span跨越若干轨道 */
.item {
grid-column: span 2; /* 跨越2列 */
grid-row: span 3; /* 跨越3行 */
}
/* 负数从末尾计数 */
.item {
grid-column: 1 / -1; /* 从第一列到最后一列,横跨整个容器 */
}
3.2 网格线命名
通过方括号语法为网格线命名,使定位更可读:
.grid {
display: grid;
grid-template-columns: [sidebar-start] 250px [sidebar-end content-start] 1fr [content-end];
grid-template-rows: [header-start] 80px [header-end main-start] 1fr [main-end footer-start] 60px [footer-end];
}
.header { grid-row: header-start / header-end; grid-column: 1 / -1; }
.sidebar { grid-row: main-start / main-end; grid-column: sidebar-start / sidebar-end; }
.main { grid-row: main-start / main-end; grid-column: content-start / content-end; }
.footer { grid-row: footer-start / footer-end; grid-column: 1 / -1; }
四、网格区域模板
4.1 grid-template-areas
grid-template-areas提供了最直观的布局方式——通过ASCII模板定义布局:
.layout {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 80px 1fr 60px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
使用点号(.)表示空单元格:
grid-template-areas:
"header header header"
"sidebar . main"
"footer footer footer";
4.2 grid-area 简写
grid-area可以同时指定四条线:
/* grid-area: row-start / column-start / row-end / column-end */
.item {
grid-area: 1 / 2 / 3 / 4;
/* 等同于:从第1行线到第3行线,从第2列线到第4列线 */
}
五、间距与对齐
5.1 网格间距(Gap)
.grid {
gap: 20px; /* 行列间距相同 */
row-gap: 20px; /* 行间距 */
column-gap: 30px; /* 列间距 */
gap: 20px 30px; /* 行间距 列间距 */
}
5.2 项目对齐(align/justify)
Grid提供了一套完整的对齐系统:
/* 容器级别:所有项目整体对齐 */
.grid {
justify-content: center; /* 列方向:start | end | center | stretch | space-around | space-between | space-evenly */
align-content: center; /* 行方向:同上 */
}
/* 项目级别:单个项目在自身单元格内对齐 */
.item {
justify-self: center; /* 列方向 */
align-self: center; /* 行方向 */
}
/* 简写 */
.item {
place-self: center center; /* align-self justify-self */
}
.grid {
place-content: center center; /* align-content justify-content */
}
六、高级技巧
6.1 重叠与z-index
Grid天然支持项目重叠,通过z-index控制堆叠顺序:
.grid {
grid-template-columns: repeat(3, 1fr);
}
.overlay {
grid-column: 1 / 3;
grid-row: 1 / 3;
z-index: 2;
}
.background {
grid-column: 2 / 4;
grid-row: 1 / 3;
z-index: 1;
opacity: 0.5;
}
6.2 子网格(Subgrid)
Subgrid允许嵌套网格继承父网格的轨道定义,解决对齐一致性问题:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.card {
display: grid;
grid-template-rows: subgrid; /* 继承父网格的行轨道 */
grid-row: span 3;
}
/* 卡片内的标题、描述、底部会自动与同行其他卡片对齐 */
6.3 使用 container queries 配合 Grid
现代CSS中,将Grid与容器查询结合,可以实现组件级的响应式:
.card-container {
container-type: inline-size;
display: grid;
grid-template-rows: auto 1fr auto;
}
@container (min-width: 600px) {
.card {
grid-template-columns: 200px 1fr;
grid-template-rows: auto;
}
}
七、实战案例
7.1 Holy Grail布局
.page {
display: grid;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
@media (max-width: 768px) {
.page {
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
grid-template-columns: 1fr;
}
}
7.2 响应式图片画廊
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 16px;
}
.gallery img {
width: 100%;
height: 250px;
object-fit: cover;
border-radius: 8px;
}
/* 特色图片占据更大的空间 */
.featured {
grid-column: span 2;
grid-row: span 2;
}
.featured img {
height: 100%;
}
7.3 仪表板布局
.dashboard {
display: grid;
grid-template-columns: 260px repeat(auto-fit, minmax(300px, 1fr));
grid-auto-rows: minmax(200px, auto);
gap: 20px;
}
.sidebar {
grid-column: 1;
grid-row: 1 / -1; /* 横跨所有行 */
}
.widget {
/* 每个widget自动放置到可用位置 */
}
.wide-widget {
grid-column: span 2; /* 宽widget占2列 */
}
八、Grid vs Flexbox选型指南
| 场景 | 推荐方案 |
|---|---|
| 整体页面布局(页头/侧栏/主体/页脚) | Grid(二维) |
| 导航栏、按钮组、标签栏 | Flexbox(一维) |
| 卡片网格/图片画廊 | Grid + auto-fit |
| 表单元素对齐 | Flexbox 或 Grid 均可 |
| 不规则网格响应式布局 | Grid + 媒体查询 |
| 单项导航/左标签右按钮 | Flexbox |
| 需要精确对齐多个维度 | Grid |
九、浏览器兼容性与降级策略
Grid在现代浏览器中拥有极佳的支持率(全球约97%+)。对于需要支持旧版本浏览器的项目,可以采用渐进增强策略:
/* 基础布局:使用Flexbox或float */
.layout {
display: flex;
flex-wrap: wrap;
}
.layout > * {
flex: 1 1 300px;
}
/* 增强布局:支持Grid的浏览器使用Grid */
@supports (display: grid) {
.layout {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
}
总结
CSS Grid是现代Web布局的核心工具,掌握它能够让你摆脱对绝对定位和复杂浮动的依赖。关键要点回顾:
- Grid处理二维布局,Flexbox处理一维布局,两者互补而非替代
- fr单位 + auto-fit/auto-fill实现了无需媒体查询的响应式网格
- grid-template-areas让复杂布局一目了然
- Subgrid解决了嵌套组件的对齐一致性问题
- @supports渐进增强确保兼容性
从今天开始告别布局hack,拥抱Grid带来的纯粹与优雅。

发表评论 取消回复