前端开发里,“把页面元素排整齐”从来不是件简单事。
你可能用过float
浮动(容易塌陷)、position
定位(脱离文档流难管理),甚至刚学会Flexbox
(擅长排成一条线),但遇到同时要管行和列的二维布局(比如卡片列表、导航栏+主内容+侧边栏),这些工具总像“缺了一条腿”。
这时候,CSS Grid布局站出来了——它像一把“二维布局瑞士军刀”,能精准划分行和列,把元素“贴”到指定格子里。哪怕是复杂的页面结构,也能用几行代码搞定。
今天我们从基础概念讲到实战技巧,重点拆解新手最常用的grid-template-columns: repeat(3, 1fr)
,帮你彻底搞懂Grid,从此布局不犯愁。
一、先搞懂:Grid到底是什么?
一句话总结:CSS Grid是专门用于二维布局的CSS模块。
把它想象成一张“电子方格纸”——你能先画好行和列的格子(轨道),再把页面元素(项目)精准放进任意格子里。
和Flexbox的核心区别:
- Flexbox是“一维的”:只能排成一条线(横向或纵向),比如导航栏的按钮排列;
- Grid是“二维的”:能同时管行和列,比如商品详情页的“图片+描述+价格”布局。
二、必须记住的4个核心概念(新手入门钥匙)
学习Grid前,先搞懂这几个术语,后面看代码会像“看地图”一样清晰:
1. 容器(Grid Container)& 项目(Grid Item)
- 容器:给父元素加
display: grid
,它就成了“网格画布”,负责定义行和列; - 项目:容器的直接子元素(注意是“直接”,嵌套的子元素不算),是要放进网格的元素。
比如:
<div class="container"> <!-- 容器 -->
<div>卡片1</div> <!-- 项目 -->
<div>卡片2</div> <!-- 项目 -->
<div>卡片3</div> <!-- 项目 -->
</div>
2. 网格线(Grid Line):网格的“边框”
水平和垂直的“隐形线”,用来定位项目的位置。
- 水平线从上到下编号(1、2、3…);
- 垂直线从左到右编号(1、2、3…)。
比如你想把项目放在“第2条竖线到第4条竖线,第1条横线到第3条横线”之间,用grid-column: 2/4; grid-row: 1/3;
就能实现。
3. 网格轨道(Grid Track):格子的“宽度/高度”
- 行轨道:两条相邻水平线之间的空间(即一行);
- 列轨道:两条相邻垂直线之间的空间(即一列)。
轨道大小可以用px
(固定)、%
(相对父容器)或fr
(分数,比如1fr
占1份剩余空间)定义。
4. 网格单元格&网格区域
- 单元格:一行+一列交叉的小格子(类似Excel的一个单元格);
- 区域:多个连续单元格组成的矩形块(比如跨2行2列的大格子,用
grid-area: 1/1/3/3;
定义)。
三、动手搭个基础Grid布局:3步搞定卡片列表
现在用一个真实场景练习:做3个等宽卡片,横向排列,超出换行。
步骤1:开启Grid模式(定义容器)
给父元素加display: grid
,它就成了“网格画布”:
.container {
display: grid; /* 关键:开启Grid布局 */
}
步骤2:画好列和行的“格子”
用grid-template-columns
定义列轨道,grid-template-rows
定义行轨道:
.container {
display: grid;
grid-template-columns: 150px 150px 150px; /* 3列,每列150px */
grid-template-rows: 200px; /* 1行,高度200px */
}
步骤3:调整间隙(让布局更透气)
用gap
属性设置行列间距(替代老版的grid-gap
):
.container {
display: grid;
grid-template-columns: 150px 150px 150px;
grid-template-rows: 200px;
gap: 20px; /* 行列间隙都是20px */
}
这时候你会发现:
- 3个项目刚好填满一行;
- 再加1个项目,会自动换到第二行(Grid默认允许换行:
grid-auto-flow: row
)。
四、重点拆解:grid-template-columns: repeat(3, 1fr)
——Grid的高效技巧
上面的例子中,grid-template-columns: 150px 150px 150px
写起来有点麻烦。有没有更简洁的方式?
答案就是:grid-template-columns: repeat(3, 1fr)
。
这行代码是Grid新手最常遇到的“高效写法”,今天我们拆成零件讲逻辑:
1. 先拆分:repeat()
和1fr
是什么?
grid-template-columns
:“主命令”,负责定义列轨道;repeat(3, 1fr)
:“参数”,意思是“把1fr
重复3次”。
2. repeat()
:Grid的“复印机”
repeat()
是Grid专门设计的“重复函数”,用来减少重复代码。
格式:repeat(重复次数, 要重复的轨道值)
。
比如:
repeat(3, 1fr)
→ 重复3次“1fr”→ 3列,每列1fr;repeat(2, 200px 100px)
→ 重复“200px+100px”→ 4列(200px、100px、200px、100px)。
为什么要用它?
比如要写10列“1fr”,不用repeat()
得写10遍,用它一行搞定——让代码更简洁,更易维护。
3. 1fr
:Grid的“公平分蛋糕器”
fr
是“fraction(分数)”的缩写,1fr
的意思是:把当前“剩余空间”分成1份,占满它。
举个生活化的例子:
假设容器宽度是900px,用grid-template-columns: repeat(3, 1fr)
:
- 总剩余空间 = 容器宽度(900px)- 项目的固有宽度(默认0);
- 3列各占1份 → 每列宽度=900px÷3=300px。
如果容器变宽到1200px?每列自动变成400px——1fr
会动态适配容器宽度,比固定像素(比如300px)灵活得多。
4. 合起来:这行代码到底干了什么?
grid-template-columns: repeat(3, 1fr)
的本质是:
给容器画3条列轨道,每条轨道的宽度都是“容器剩余空间的1/3”。
它的效果和grid-template-columns: 1fr 1fr 1fr
完全一样,但写法更简洁,语义更明确(“重复3次1fr”比“写3遍1fr”更易读)。
五、实战升级:用它做响应式布局
Grid的真正威力在响应式设计——不用改HTML,只改CSS就能适配不同屏幕。
比如我们要做:
- 小屏幕(<600px):1列;
- 中屏幕(600px-900px):2列;
- 大屏幕(>900px):3列。
只需要用media query
调整repeat()
的次数:
.container {
display: grid;
gap: 20px;
/* 默认:小屏幕1列 */
grid-template-columns: repeat(1, 1fr);
}
/* 中屏幕:2列 */
@media (min-width: 600px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
/* 大屏幕:3列 */
@media (min-width: 900px) {
.container {
grid-template-columns: repeat(3, 1fr);
}
}
这样改完后,卡片会随着屏幕变宽自动调整列数——真正的“一次编写,到处适配”。
六、新手必避的2个坑
1. 容器和项目要“直接对应”
只有容器的直接子元素才是项目,嵌套的子元素不会自动成为项目。
比如:
<div class="container">
<div class="card"> <!-- 项目 -->
<div class="card-content"> <!-- 不是项目,除非.card也是Grid容器 -->
内容
</div>
</div>
</div>
2. 别忘了设置轨道尺寸
如果只写display: grid
但没设置grid-template-columns
或grid-template-rows
,项目会挤成一团(默认轨道大小是auto
,元素会按内容宽度排列,导致布局混乱)。
一定要记得:先画格子(定义轨道尺寸),再放元素。
七、最后:这行代码的价值
grid-template-columns: repeat(3, 1fr)
是Grid布局里**“高效+灵活”的典型用法**:
- 用最少代码实现等宽多列;
- 自动适配容器宽度;
- 配合媒体查询轻松实现响应式。
总结:Grid其实很简单
从基础概念到实战属性,Grid的学习曲线比你想象中友好。
下次遇到需要二维排列的页面(比如导航栏+主内容+侧边栏、卡片列表、商品网格),不妨试试用Grid替代传统方案——你会发现,原来布局可以这么“丝滑”。
动手建议:
打开VS Code,敲一遍上面的例子,改一改repeat
的次数、gap
的大小,看看布局怎么变——实践是最好的老师!
评论