CSS Grid 是什么?
CSS Grid Layout 是CSS中第一个专门为布局设计的二维布局系统。与Flexbox的一维布局不同,Grid可以同时处理行和列,让你能够轻松创建复杂的页面布局,而无需使用浮动、定位或复杂的嵌套结构。
Grid布局的浏览器兼容性已经非常好,所有现代浏览器(Chrome、Firefox、Safari、Edge)都完全支持CSS Grid。
CSS Grid 和 Flexbox 不是竞争关系,而是互补的。Grid 适合整体页面布局和二维组件,Flexbox 适合组件内部的一维排列。
Grid 容器基础
要使用Grid布局,首先需要将一个元素声明为Grid容器:
.grid-container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
gap: 16px;
min-height: 100vh;
}
grid-template-columns 和 grid-template-rows
这两个属性定义网格的列和行结构,是Grid布局的核心。
/* 固定值 */
.grid {
grid-template-columns: 200px 300px 200px;
}
/* 使用 fr 单位(分数比例) */
.grid {
grid-template-columns: 1fr 2fr 1fr; /* 三列,中间是两侧的两倍宽 */
}
/* 混合使用 */
.grid {
grid-template-columns: 200px 1fr 2fr; /* 第一列200px,其余按比例分配 */
}
/* 重复函数 */
.grid {
grid-template-columns: repeat(3, 1fr); /* 三等分 */
}
/* minmax() 结合 */
.grid {
grid-template-columns: repeat(3, minmax(200px, 1fr));
}
fr 单位详解
fr(fraction)单位代表网格容器中可用空间的一个份额。它类似于Flexbox中的 flex-grow,但更直观。
| 定义 | 效果 |
|---|---|
grid-template-columns: 1fr 1fr 1fr |
三等分,每列占容器的1/3 |
grid-template-columns: 1fr 2fr 1fr |
四份分配:第一列1/4,第二列2/4,第三列1/4 |
grid-template-columns: 200px 1fr |
第一列固定200px,第二列占据剩余空间 |
auto-fill 与 auto-fit
这两个关键字与 minmax() 结合使用,可以创建完全自适应的网格。
/* auto-fill:创建尽可能多的列,空轨道保留 */
.auto-fill {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
/* auto-fit:创建尽可能多的列,空轨道折叠 */
.auto-fit {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
关键区别:auto-fill 会保留空的轨道,即使没有内容填充;auto-fit 会将空轨道折叠,让已有内容的轨道占据更多空间。
Grid Item 定位
Grid Item(子元素)可以通过多种属性控制其在网格中的位置和跨度。
grid-column 和 grid-row
.item {
/* 从第1条线到第3条线(跨越2列) */
grid-column: 1 / 3;
/* 从第1条线到第3条线(跨越2行) */
grid-row: 1 / 3;
/* 简写:跨越2列 */
grid-column: span 2;
/* 从第2条线开始,跨越3列 */
grid-column: 2 / span 3;
}
/* 使用 -1 引用最后一条线 */
.item {
grid-column: 1 / -1; /* 占满所有列 */
}
grid-area 命名网格区域
/* 定义命名区域 */
.layout {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
gap: 16px;
min-height: 100vh;
}
/* 将子元素分配到对应区域 */
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
对齐方式
Grid提供了丰富的对齐属性,控制项目在网格单元格中的位置。
| 属性 | 作用 | 可用值 |
|---|---|---|
justify-items |
水平对齐(行内方向) | start / end / center / stretch |
align-items |
垂直对齐(块方向) | start / end / center / stretch |
place-items |
简写(align + justify) | center / start end 等 |
justify-content |
网格在容器中的水平位置 | start / end / center / space-between 等 |
align-content |
网格在容器中的垂直位置 | start / end / center / space-between 等 |
/* 所有子项居中 */
.grid {
display: grid;
place-items: center;
}
/* 单个子项覆盖对齐 */
.grid-item {
justify-self: end;
align-self: start;
}
实战:响应式画廊布局
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
padding: 16px;
}
.gallery-item {
border-radius: 8px;
overflow: hidden;
aspect-ratio: 1;
}
.gallery-item img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.gallery-item:hover img {
transform: scale(1.05);
}
/* 特定项目跨越多列 */
.gallery-item.featured {
grid-column: span 2;
grid-row: span 2;
aspect-ratio: auto;
}
实战:经典圣杯布局
.holy-grail {
display: grid;
grid-template:
"header header header" auto
"nav main aside" 1fr
"footer footer footer" auto
/ 200px 1fr 200px;
min-height: 100vh;
gap: 0;
}
.header { grid-area: header; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
/* 移动端:单列布局 */
@media (max-width: 768px) {
.holy-grail {
grid-template:
"header" auto
"nav" auto
"main" 1fr
"aside" auto
"footer" auto
/ 1fr;
}
}
Grid 与 Flexbox 对比
| 特性 | CSS Grid | Flexbox |
|---|---|---|
| 维度 | 二维(行和列同时控制) | 一维(行或列) |
| 布局方向 | 任意方向,可以同时 | 沿一个轴方向排列 |
| 内容优先 vs 布局优先 | 布局优先 | 内容优先 |
| 重叠 | 原生支持(grid-column/row) | 需要额外定位 |
| 最佳用途 | 页面整体布局、复杂网格 | 导航栏、卡片内部、组件排列 |
| 间距控制 | gap 属性 | gap 属性(也支持) |
性能与最佳实践
- 优先使用
repeat()和fr单位,减少重复代码 - 使用
auto-fit/auto-fit+minmax()创建完全响应式网格,无需媒体查询 - 命名网格区域提高代码可读性和维护性
- 避免过度嵌套Grid,保持结构简洁
- 利用
gap属性替代 margin 来控制间距 - Grid 适合布局,Flexbox 适合对齐,根据场景选择合适的工具