Grid 是一种二维布局系统,既能控制行(row)又能控制列(column),相比Flex布局更适合做卡片布局以及响应式栅格系统。
一、基本语法
1.设置网格容器
display: grid;
2.设置列
fr单位:是Grid布局中专用的分数单位,用于按比例分配网格容器中的可用空间。
<div class="container">
<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
</div>
<style>
.container {
display: grid;
/* 设置每行3列,第1列宽度固定为100px,第2列占剩余宽度的1/3,第3列占剩余宽度的2/3 */
grid-template-columns: 100px 1fr 2fr;
gap: 20px;
div {
height: 200px;
background-color: #fffacd;
border-radius: 10px;
}
}
</style>

repeat()函数:是Grid布局中的工具函数,用于重复创建相同模式的网格轨道,减少重复代码。
// 设置5列自适应的网格
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
// 等价于
grid-template-columns: repeat(5, 1fr);

auto-fill参数:尽可能多地创建轨道(即使空轨道也会保留空间)
// 自动填充尽可能多的150px宽的列
grid-template-columns: repeat(auto-fill, 150px);

3.设置行
<div class="container">
<div>A</div>
<div>B</div>
<div>C</div>
<div>
<div>D1</div>
<div>D2</div>
<div>D3</div>
</div>
</div>
<style>
body {
margin: 0;
font-size: 30px;
}
.container {
display: grid;
grid-template-columns: repeat(2, 1fr);
/* 第1行高度固定为50px,第2行自动调整根据内容撑开 */
grid-template-rows: 50px auto;
gap: 20px;
div {
background-color: #fffacd;
border-radius: 10px;
}
}
</style>

4.控制某个网格的位置
想让某个网格跨行跨列展示,可以使用grid-column、grid-row设置网格线的范围来控制。
<div class="container">
<div class="box">A</div>
<div>B</div>
<div>C</div>
<div>D</div>
<div>E</div>
<div>F</div>
<div>G</div>
<div>H</div>
<div>I</div>
<div>J</div>
<div>K</div>
</div>
<style>
.container {
padding: 20px;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
div {
height: 100px;
background-color: #fffacd;
border-radius: 10px;
}
.box {
/* 设置列的内容范围从第1条网格线开始到第3条网格线结束 */
grid-column: 1 / 3;
/* 设置行的内容范围从第2条网格线开始到第4条网格线结束, */
grid-row: 2 / 4;
height: 100%;
background-color: #fff0f5;
}
}
</style>

5.设置行与列之间的间隙
// 设置网格之间的间距
gap:20px;
// 等价于
row-gap: 10px;
column-gap: 10px;
6.响应式布局
minmax()函数:定义网格轨道的尺寸范围,使布局更灵活
auto-fit参数:自动填充尽可能多的列
<div class="container">
<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
<div>E</div>
<div>F</div>
<div>G</div>
<div>H</div>
<div>I</div>
<div>J</div>
<div>K</div>
</div>
<style>
.container {
padding: 20px;
display: grid;
/* 每列最小宽度为100px,最多占满剩余空间,填充尽可能多的列 */
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 20px;
div {
height: 100px;
background-color: #fffacd;
border-radius: 10px;
}
}
</style>

二、兼容性
需要注意grid、gap的兼容性:
兼容性 | gap 支持 | 建议用法 | |
Flex | ✅ 极好 | ⚠️ Safari 14.1+ 才支持 gap | 一维布局最佳选择 |
Grid | ✅ iOS11+ 安全使用 | ✅ Safari 10.1+ 才支持 | 二维/响应式布局推荐 |
gap in Flex | ❌ iOS14以下无效,IE11不支持 | ❌ | 保守使用,推荐用 margin |
下面是一个响应式网格卡片布局示例,旧版不支持 Grid 时自动回退到Flex,兼容 ios10+ :
<div class="container">
<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
<div>E</div>
<div>F</div>
<div>G</div>
<div>H</div>
<div>I</div>
<div>J</div>
<div>K</div>
</div>
<style>
.container {
padding: 20px;
display: flex;
flex-wrap: wrap;
margin: -10px;
div {
width: 100px;
height: 100px;
margin: 10px;
background-color: #fffacd;
border-radius: 10px;
}
}
/* 检测支持 Grid 时启用 Grid 布局 */
@supports (display: grid) {
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 20px;
margin: 0;
div {
width: auto;
margin: 0;
}
}
}
</style>