Grid 布局
约 2404 字大约 8 分钟
cssgrid
2026-04-16
1. Grid 简介
Grid 布局(CSS Grid Layout)是一种二维布局系统,可以同时处理行和列的布局。与 Flexbox 的单轴布局不同,Grid 布局更适合构建复杂的页面布局。
Grid vs Flexbox
| 特性 | Grid | Flexbox |
|---|---|---|
| 维度 | 二维(行+列) | 一维(行或列) |
| 控制方式 | 父容器控制子项位置 | 子项自己决定分布 |
| 适用场景 | 整体页面布局、复杂栅格 | 组件内部布局、导航菜单 |
| 对齐方式 | 丰富(轨道对齐、区域对齐) | 主轴/交叉轴对齐 |
| 典型应用 | 圣杯布局、相册墙、仪表盘 | 导航栏、卡片列表、表单 |
何时使用 Grid
- 需要同时控制行和列的布局
- 需要创建规整的栅格系统
- 页面整体布局,如 header、sidebar、main、footer
- 需要对齐的二维表格化内容
- 布局比内容更重要时(Grid 优先)
何时使用 Flexbox
- 一维分布,如水平导航栏
- 内容决定大小,容器适配内容
- 组件内部布局,如卡片内元素排列
- 需要自动换行时
2. 容器属性(Grid Container)
2.1 display
/* 块级 Grid 容器 */
display: grid;
/* 行内 Grid 容器 */
display: inline-grid;2.2 grid-template-columns / grid-template-rows
定义网格的列和行轨道。
基本单位:
| 单位 | 说明 |
|---|---|
px | 固定像素 |
% | 相对于容器的百分比 |
fr | 份数(fraction),剩余空间的分配单位 |
auto | 自动适应内容 |
min-content | 最小内容尺寸 |
max-content | 最大内容尺寸 |
repeat() 函数:
/* 3 等分列 */
grid-template-columns: repeat(3, 1fr);
/* 重复模式:2列100px,然后1列1fr */
grid-template-columns: repeat(2, 100px) 1fr;
/* auto-fill:尽可能多地填充列 */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* auto-fit:与 auto-fill 类似,但空列会被合并 */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));auto-fill vs auto-fit 区别:
/* 容器宽度 800px,子项最小 200px */
/* auto-fill:会保留空列位置 */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* 结果:4列(200px*4=800px),最后一项拉伸 */
/* auto-fit:空列被合并拉伸已有项 */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* 结果:4列全部拉伸填满 800px */2.3 grid-template-areas
通过命名区域来定义布局。
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }2.4 gap
定义网格轨道之间的间距。
/* 行间距和列间距 */
gap: 20px;
/* 分别设置行间距和列间距 */
gap: 20px 30px;
/* 单独设置 */
row-gap: 20px;
column-gap: 30px;
/* 兼容旧语法 */
grid-gap: 20px; /* 已废弃 */
grid-row-gap: 20px; /* 已废弃 */
grid-column-gap: 30px; /* 已废弃 */2.5 grid-template(简写)
/* grid-template 是 grid-template-rows、grid-template-columns、grid-template-areas 的简写 */
grid-template:
"header header" 60px
"sidebar main" 1fr
"footer footer" 60px
/ 200px 1fr;2.6 justify-items
定义网格项在单元格内的水平对齐方式。
/* 默认值,stretch 拉伸填满 */
justify-items: stretch;
/* 起点对齐 */
justify-items: start;
/* 终点对齐 */
justify-items: end;
/* 居中对齐 */
justify-items: center;2.7 align-items
定义网格项在单元格内的垂直对齐方式。
/* 默认值,stretch 拉伸填满 */
align-items: stretch;
/* 起点对齐 */
align-items: start;
/* 终点对齐 */
align-items: end;
/* 居中对齐 */
align-items: center;
/* 基线对齐 */
align-items: baseline;2.8 justify-content
定义整个网格在容器内的水平对齐(当网格总宽度小于容器时)。
justify-content: start; /* 左对齐 */
justify-content: end; /* 右对齐 */
justify-content: center; /* 居中 */
justify-content: stretch; /* 拉伸填充 */
justify-content: space-between; /* 两端对齐 */
justify-content: space-around; /* 环绕间距 */
justify-content: space-evenly; /* 等间距 */2.9 align-content
定义整个网格在容器内的垂直对齐(当网格总高度小于容器时)。
align-content: start; /* 顶部对齐 */
align-content: end; /* 底部对齐 */
align-content: center; /* 垂直居中 */
align-content: stretch; /* 拉伸填充 */
align-content: space-between;
align-content: space-around;
align-content: space-evenly;2.10 grid-auto-flow
控制自动放置算法的行为。
/* 默认:按行依次放置 */
grid-auto-flow: row;
/* 按列依次放置 */
grid-auto-flow: column;
/* 密集打包:尽可能填满空位 */
grid-auto-flow: dense;
grid-auto-flow: row dense;3. 项目属性(Grid Items)
3.1 grid-column / grid-row
定义项目跨越的列或行轨道。
/* 简写形式 */
grid-column: 1 / 3; /* 从第1条线到第3条线(跨2列) */
grid-row: 1 / 3; /* 从第1条线到第3条线(跨2行) */
grid-column: 1 / span 2; /* 从第1条线开始,跨2列 */
grid-row: 1 / span 2; /* 从第1条线开始,跨2行 */
grid-column: 1 / -1; /* 跨越所有列 */
/* 单独写法 */
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 3;3.2 grid-area
定义项目所在的命名区域,或指定位置。
/* 指定区域名称 */
grid-area: header;
/* 指定行列位置:row-start / col-start / row-end / col-end */
grid-area: 1 / 1 / 3 / 3;3.3 justify-self
定义单个项目在单元格内的水平对齐。
justify-self: stretch; /* 默认值 */
justify-self: start;
justify-self: end;
justify-self: center;3.4 align-self
定义单个项目在单元格内的垂直对齐。
align-self: stretch;
align-self: start;
align-self: end;
align-self: center;
align-self: baseline;3.5 grid-column-start / grid-column-end / grid-row-start / grid-row-end
更精细地控制项目的起止位置。
grid-column-start: 2;
grid-column-end: 5;
grid-row-start: 1;
grid-row-end: 4;4. 命名网格线
可以为网格线指定名称,便于布局和阅读。
.container {
display: grid;
grid-template-columns:
[sidebar-start] 200px
[sidebar-end content-start] 1fr
[content-end];
grid-template-rows:
[header-start] 60px
[header-end main-start] 1fr
[main-end footer-start] 60px
[footer-end];
}
/* 使用命名线条定位 */
.header {
grid-column: sidebar-start / sidebar-end;
grid-row: header-start / header-end;
}
.sidebar {
grid-column: sidebar-start / sidebar-end;
grid-row: main-start / main-end;
}
.main {
grid-column: content-start / content-end;
grid-row: main-start / main-end;
}5. 常用布局场景
5.1 经典 12 栅格系统
/* 12 列栅格系统 */
.grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 20px;
}
.col-1 { grid-column: span 1; }
.col-2 { grid-column: span 2; }
.col-3 { grid-column: span 3; }
.col-4 { grid-column: span 4; }
.col-6 { grid-column: span 6; }
.col-8 { grid-column: span 8; }
.col-12 { grid-column: span 12; }
/* 响应式栅格 */
@media (max-width: 768px) {
[class*="col-"] {
grid-column: span 12;
}
}<div class="grid">
<div class="col-3">3列</div>
<div class="col-6">6列</div>
<div class="col-3">3列</div>
</div>5.2 圣杯布局
经典的三栏布局:header、footer 固定高度,sidebar 左右固定,中间 main 自适应。
.holy-grail {
display: grid;
grid-template:
"header header header" 60px
"sidebar main aside" 1fr
"footer footer footer" 60px
/ 200px 1fr 200px;
height: 100vh;
gap: 10px;
}
.holy-grail > header {
grid-area: header;
background: #3498db;
}
.holy-grail > .sidebar {
grid-area: sidebar;
background: #2ecc71;
}
.holy-grail > main {
grid-area: main;
background: #ecf0f1;
}
.holy-grail > .aside {
grid-area: aside;
background: #9b59b6;
}
.holy-grail > footer {
grid-area: footer;
background: #34495e;
}
/* 响应式:移动端堆叠布局 */
@media (max-width: 768px) {
.holy-grail {
grid-template:
"header" 60px
"main" 1fr
"aside" auto
"sidebar" auto
"footer" 60px
/ 1fr;
}
}5.3 杂志布局
多列多行的复杂图文混排布局。
.magazine {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, auto);
gap: 20px;
}
/* 大图占2列2行 */
.feature {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
/* 横向文章占满整行 */
.horizontal {
grid-column: 1 / -1;
}
/* 小卡片 */
.card {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
}<div class="magazine">
<article class="card feature">
<h2>专题报道</h2>
<p>占据左上角 2x2 的大区块</p>
</article>
<article class="card">
<h3>文章1</h3>
</article>
<article class="card">
<h3>文章2</h3>
</article>
<article class="card horizontal">
<h3>横向文章</h3>
</article>
<article class="card">
<h3>文章3</h3>
</article>
<article class="card">
<h3>文章4</h3>
</article>
</div>6. 与 Flexbox 的选择建议
| 场景 | 推荐 | 原因 |
|---|---|---|
| 页面整体布局 | Grid | 二维控制,页面结构清晰 |
| 导航菜单 | Flexbox | 一维分布更灵活 |
| 卡片网格 | Grid | 行列对齐简单 |
| 表单布局 | Flexbox | 标签和输入框对齐 |
| 居中弹窗 | Flexbox 或 Grid | Grid 只需两行代码 |
| 图文混排 | Grid | 复杂的行列控制 |
| 组件内元素排列 | Flexbox | 内容驱动布局 |
| 等高卡片列 | Grid | align-items: stretch 天然支持 |
实际工作中的策略
/* 页面布局用 Grid */
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
/* 组件内部用 Flexbox */
.card {
display: flex;
flex-direction: column;
justify-content: space-between;
}
/* 也可以组合使用 */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
.card-grid > .card {
display: flex;
flex-direction: column;
}7. 完整示例
Dashboard 仪表盘布局
.dashboard {
display: grid;
grid-template-columns: 260px 1fr;
grid-template-rows: 64px 1fr;
grid-template-areas:
"sidebar header"
"sidebar main";
height: 100vh;
}
.dashboard > .sidebar {
grid-area: sidebar;
background: linear-gradient(180deg, #1a1a2e 0%, #16213e 100%);
}
.dashboard > .header {
grid-area: header;
background: #fff;
box-shadow: 0 1px 4px rgba(0,0,0,0.1);
}
.dashboard > .main {
grid-area: main;
background: #f5f7fa;
padding: 24px;
overflow-y: auto;
}
/* 主内容区域使用 Grid 排列卡片 */
.metrics {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
margin-bottom: 24px;
}
.chart-card {
grid-column: span 2;
background: #fff;
border-radius: 12px;
padding: 20px;
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}8. 浏览器兼容性
| 特性 | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Grid 基础 | 57+ | 52+ | 10.1+ | 16+ |
| grid-template-areas | 57+ | 52+ | 10.1+ | 16+ |
| gap | 66+ | 61+ | 12+ | 16+ |
| auto-fill/auto-fit | 57+ | 52+ | 10.1+ | 16+ |
| 命名网格线 | 57+ | 52+ | 10.1+ | 16+ |
注意:IE 11 仅支持部分 Grid 特性(-ms 前缀的旧语法),生产环境需根据目标用户考虑兼容需求。
参考文章:
