CSS Grid 布局是一种二维的布局系统,与 Flex 布局(Flexbox)仅关注一维(行或列)不同,Grid 能够同时处理行和列的布局,通过创建网格容器和网格项目,实现对网页元素的精确控制。它引入了一系列独特的术语,如网格线
、轨道
、单元格
和网格区域
,为开发者提供了强大且灵活的布局能力。
CSS Grid 布局
基本概念
-
网格容器(Grid Container):通过
display: grid
或display: inline-grid
属性声明的元素,是所有网格项目的父级容器。 -
网格项目(Grid Item):网格容器内的直接子元素,会自动成为网格的一部分。
-
网格线(Grid Line):水平和垂直方向上划分网格的线,从 1 开始编号,也支持负数索引(-1 表示最后一条线)。
-
轨道(Track):两条相邻网格线之间的空间,分为行轨道(由
grid-template-rows
定义)和列轨道(由grid-template-columns
定义)。 -
单元格(Cell):由四条网格线包围形成的最小单位。
-
网格区域(Grid Area):由多个相邻单元格组成的矩形区域,可以通过命名进行引用和定位。
显式网格与隐式网格
-
显式网格:开发者通过
grid-template-rows
和grid-template-columns
手动定义的行列轨道,对网格结构进行精确控制。 -
隐式网格:当网格项目数量超出显式网格范围时,由
grid-auto-rows
和grid-auto-columns
自动生成的额外轨道,用于容纳多余的项目。
核心属性
1.轨道定义
通过grid-template-rows
和grid-template-columns
属性定义行和列轨道的尺寸,常见单位包括像素(px)、百分比(%)、fr
(弹性单位)等。
fr单位:用于分配剩余空间,如2fr
表示占据1fr
两倍的空间。
.grid-container { display: grid; /* 定义三列,第一列宽150px,第二列占剩余空间的1份,第三列宽200px */ grid-template-columns: 150px 1fr 200px; /* 定义两行,第一行高80px,第二行根据内容自动调整高度 */ grid-template-rows: 80px auto; }
效果如下图,为了方便看,针对每个子元素做了背景色处理:
2.智能轨道适配
repeat(auto-fit, minmax())
和repeat(auto-fill, minmax())
用于创建响应式网格,根据容器大小自动调整列数。
-
fr单位:用于分配剩余空间,如
2fr
表示占据1fr
两倍的空间。 -
minmax(min, max)函数:指定轨道的最小和最大尺寸,例如
minmax(100px, auto)
表示轨道最小为 100px,最大可根据内容自动扩展。 -
repeat()函数:简化轨道重复定义,如
repeat(3, 1fr)
等同于1fr 1fr 1fr
。
/* 自动适配,列宽最小250px,最大占据剩余空间,高度自适应 */ .gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); grid-gap: 15px; /* 设置每个各自上下左右间距15px */ }
-
auto-fit:优先填满容器,多余列收缩或换行。
-
auto-fill:尽可能填充列,即使容器空间不足,多余列也会保留。
当父级容器宽度不确定时,就可以给子元素设置一个最小宽度,然后让其自适应父级宽度每行显示不同的列数:
3.命名网格区域
使用grid-template-areas
属性为网格区域命名,方便项目定位。
同时要在子元素中声明grid-area
当前元素所在的区域位置
<div class="layout"> <header>Header</header> <main>Main Content</main> <aside>Sidebar</aside> <ads>ads</ads> <footer>Footer</footer> </div> <style> .layout { display: grid; grid-template-areas: "header header header" "aside main ads" "footer footer footer"; /* 定义三列,第一列宽200px,第二列占剩余空间的1份,第三列宽150px */ grid-template-columns: 200px 1fr 150px; /* 定义两行,第一行高60px,第二行根据内容自动调整高度,第三行高40px */ grid-template-rows: 60px 1fr 40px; } .layout header { /* 指定当前元素所在的区域位置,从 grid-template-areas 选取值 */ grid-area: header; background: #4078cb; } .layout aside { grid-area: aside; background: #e5e5e5; } .layout main { grid-area: main; background: #eeee; } .layout footer { grid-area: footer; background: gray; } </style>
-
每个字符串代表一行,空格分隔区域名称,
.
表示空区域。
4.间距控制
grid-column-gap
和grid-row-gap
分别设置列与列、行与行之间的间距,grid-gap
是两者的简写形式。
.grid-container-gap { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); grid-template-rows: 80px 80px 80px; /* 行间距为50 */ grid-row-gap: 50px; /* 列间距为30 */ grid-column-gap: 30px; /* 等价于 */ /* grid-gap: 50px 30px; */ }
5.对齐体系控制
两个维度控制
-
主轴对齐 (Justify):水平方向(默认行方向)
-
交叉轴对齐 (Align):垂直方向(默认列方向)
两个层级控制
-
容器级:统一设置所有单元格对齐方式
-
项目级:单独设置特定单元格对齐方式
justify-content
控制网格内容在水平方向的对齐,align-content
控制垂直方向的对齐。
.grid-container { justify-content: center; /* 水平居中 */ align-content: space-around; /* 垂直方向均匀分布,两端留有空白 */ }
容器级对齐属性
属性 | 作用范围 | 控制维度 | 默认值 |
---|---|---|---|
justify-items |
所有网格项 | 水平 | stretch |
align-items |
所有网格项 | 垂直 | stretch |
justify-content |
整个网格容器 | 水平 | start |
align-content |
整个网格容器 | 垂直 | start |
项目级对齐属性
属性 | 作用范围 | 控制维度 | 继承性 |
---|---|---|---|
justify-self |
单个网格项 | 水平 | 否 |
align-self |
单个网格项 | 垂直 | 否 |
通用属性值
值 | 效果描述 | 适用场景 |
---|---|---|
start |
对齐到单元格起始边缘 | 左对齐/顶对齐 |
end |
对齐到单元格结束边缘 | 右对齐/底对齐 |
center |
单元格内居中 | 垂直水平居中 |
stretch |
拉伸填充整个单元格(默认) | 等高分栏布局 |
baseline |
按文本基线对齐 | 文本混排场景 |
特殊属性值(仅限*-content)
值 | 效果描述 |
---|---|
space-between |
均匀分布,首尾贴边 |
space-around |
均匀分布,两侧留白相等 |
space-evenly |
完全均匀分布 |
常用案例
1.自适应卡片布局
卡片最小宽度为280px,根据屏幕宽度自动分配格子宽度。
<div class="grid-container"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> </div> <style> .grid-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 30px; padding: 20px; background: #f0f0f0; } .item { background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } /* 断点优化 */ @media (max-width: 600px) { .grid-container { gap: 15px; grid-template-columns: 1fr; } } </style>
2.圣杯布局(Header + Sidebar + Main + Footer)
经典的pc端布局方式
<div class="holy-grail"> <header>Header</header> <nav>Sidebar</nav> <main>Main Content</main> <footer>Footer</footer> </div> <style> .holy-grail { display: grid; height: 100vh; grid-template: "header header" 80px "sidebar main" 1fr "footer footer" 60px / 240px 1fr; gap: 1px; background: #ddd; } header { grid-area: header; background: #2196F3; } nav { grid-area: sidebar; background: #607D8B; } main { grid-area: main; background: #fff; } footer { grid-area: footer; background: #3F51B5; } </style>
3.杂志式不规则布局
<div class="grid-container"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item">5</div> <div class="item">6</div> </div> <style> .grid-container { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: masonry; /* 实验性特性 */ gap: 20px; padding: 20px; background: #f0f0f0; } .item { background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .item:nth-child(1) { grid-column: 1 / 3; grid-row: 1 / 3; } .item:nth-child(5) { grid-column: 4; grid-row: 1 / 4; } </style>
4.标签对齐表单
<form class="form-grid"> <label>用户名:</label> <input type="text"> <label>密码:</label> <input type="password"> <label>简介:</label> <textarea></textarea> </form> <style> .form-grid { display: grid; grid-template-columns: [labels] 120px [controls] 1fr; gap: 15px; align-items: center; max-width: 600px; padding: 20px; } label { grid-column: labels; justify-self: end; } input, textarea { grid-column: controls; padding: 8px; border: 1px solid #ccc; } textarea { height: 80px; resize: vertical; } </style>
建议:先通过网格生成工具建立直观认知,再逐步手动编码实现典型布局,最后尝试重构现有项目的布局方案。