您好!作为一名资深前端开发专家,我将为您带来一份全面的 CSS Grid 布局教程,并结合丰富的案例,帮助您掌握这一强大的现代布局技术。CSS Grid Layout (CSS 网格布局) 是 CSS 的一个模块,它为 Web 开发带来了真正的二维布局能力,让复杂页面的构建变得前所未有的简单和高效。
CSS Grid 是一种强大的 CSS 布局系统,它允许您将页面内容排列成行和列的网格。与 Flexbox 主要处理一维布局(行或列)不同,Grid 能够同时在行和列两个维度上进行布局控制,这使得它非常适合构建复杂的、响应式的页面结构,例如仪表盘、画廊或整个页面的主布局。
minmax(), auto-fit/auto-fill 和媒体查询,轻松实现响应式布局。CSS Grid 布局主要涉及两个层面的概念:网格容器 (Grid Container) 和 网格项 (Grid Item)。
应用于父元素,定义网格的整体结构。
| 属性 | 说明 | 常用值 |
|---|---|---|
display |
定义元素为一个网格容器。 | grid | inline-grid |
grid-template-columns |
定义列的宽度。 | px, %, fr, auto, repeat(), minmax() |
grid-template-rows |
定义行的高度。 | px, %, fr, auto, repeat(), minmax() |
grid-gap (gap) |
定义网格线之间的间距(行间距和列间距)。 | <length> (如 10px, 1em) |
grid-template-areas |
通过命名区域来定义网格布局。 | 字符串,每个字符串代表一行,字符串中的单词代表一个区域。 |
justify-items |
网格项在单元格内部沿行轴的对齐方式。 | start | end | center | stretch |
align-items |
网格项在单元格内部沿列轴的对齐方式。 | start | end | center | stretch |
justify-content |
整个网格在容器内部沿行轴的对齐方式。 | start | end | center | stretch | space-around | space-between | space-evenly |
align-content |
整个网格在容器内部沿列轴的对齐方式。 | start | end | center | stretch | space-around | space-between | space-evenly |
grid-auto-columns |
定义隐式创建的列的大小。 | 同 grid-template-columns |
grid-auto-rows |
定义隐式创建的行的大小。 | 同 grid-template-rows |
grid-auto-flow |
控制自动放置的网格项如何排列。 | row | column | dense |
fr (fractional unit):弹性单位,表示可用空间的一部分。例如 1fr 2fr 表示第一个列占1份,第二个列占2份。repeat(n, value):重复创建 n 个指定大小的行/列。例如 repeat(3, 1fr) 等同于 1fr 1fr 1fr。minmax(min, max):定义一个尺寸范围,表示列或行的最小和最大尺寸。例如 minmax(100px, 1fr) 表示最小100px,最大1fr。auto-fit / auto-fill:配合 repeat() 和 minmax() 使用,自动填充或适应网格项。
auto-fill:会填充尽可能多的单元格,即使内容不足也会创建空单元格。auto-fit:会折叠空单元格,使得网格项尽可能地填充可用空间。应用于子元素,控制其在网格中的位置和大小。
| 属性 | 说明 | 常用值 |
|---|---|---|
grid-column-start |
网格项开始的列线。 | <line-number> | span <number> | <named-line> |
grid-column-end |
网格项结束的列线。 | <line-number> | span <number> | <named-line> |
grid-row-start |
网格项开始的行线。 | <line-number> | span <number> | <named-line> |
grid-row-end |
网格项结束的行线。 | <line-number> | span <number> | <named-line> |
grid-column |
grid-column-start 和 grid-column-end 的简写。 |
start / end |
grid-row |
grid-row-start 和 grid-row-end 的简写。 |
start / end |
grid-area |
将网格项放置在已命名的网格区域内。也可以是 row-start / column-start / row-end / column-end 的简写。 |
<named-area> | r-start / c-start / r-end / c-end |
justify-self |
单个网格项在单元格内部沿行轴的对齐方式。 | start | end | center | stretch |
align-self |
单个网格项在单元格内部沿列轴的对齐方式。 | start | end | center | stretch |
这是一个最基础的 Grid 布局,定义了两行三列,并使用 fr 单位让列宽自动分配。
<div class="grid-container">
<div class="grid-item">Header</div>
<div class="grid-item">Sidebar</div>
<div class="grid-item">Main Content</div>
<div class="grid-item">Item 4</div>
<div class="grid-item">Footer</div>
<div class="grid-item">Item 6</div>
</div>
.grid-container {
display: grid;
/* 定义三列:第一列固定 100px,后两列平均分配剩余空间 */
grid-template-columns: 100px 1fr 1fr;
/* 定义两行:第一行 50px,第二行 100px */
grid-template-rows: 50px 100px;
/* 定义行和列之间的间距 */
gap: 10px; /* 简写形式,等同于 grid-gap: 10px; */
border: 1px solid #ccc;
padding: 10px;
min-height: 150px;
}
.grid-item {
background-color: #b1d4e0;
color: #2c3e50;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
border-radius: 4px;
font-weight: bold;
}
使用 repeat(auto-fit, minmax(width, 1fr)) 实现响应式卡片网格,卡片会根据容器宽度自动调整数量和大小。
<div class="grid-container">
<div class="grid-item">Card 1</div>
<div class="grid-item">Card 2</div>
<div class="grid-item">Card 3</div>
<div class="grid-item">Card 4</div>
<div class="grid-item">Card 5</div>
<div class="grid-item">Card 6</div>
</div>
.grid-container {
display: grid;
/* 自动创建列,每列最小 100px,最大 1fr */
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 15px;
border: 1px solid #ccc;
padding: 10px;
min-height: 150px;
}
.grid-item {
background-color: #b1d4e0;
color: #2c3e50;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
border-radius: 4px;
font-weight: bold;
}
使用 grid-template-areas 通过命名区域来构建复杂的页面布局,结构清晰、易读。
<div class="grid-container">
<div class="grid-item header">Header</div>
<div class="grid-item sidebar">Sidebar</div>
<div class="grid-item main">Main Content</div>
<div class="grid-item footer">Footer</div>
</div>
.grid-container {
display: grid;
/* 定义两列:侧边栏 1fr,主内容 2fr */
grid-template-columns: 1fr 2fr;
/* 定义三行:Header、内容区、Footer */
grid-template-rows: auto 1fr auto;
/* 定义区域名称 */
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
gap: 10px;
border: 1px solid #ccc;
padding: 10px;
min-height: 250px; /* 示例高度 */
}
.header { grid-area: header; background-color: #4CAF50; color: white; }
.sidebar { grid-area: sidebar; background-color: #FFC107; }
.main { grid-area: main; background-color: #2196F3; color: white; }
.footer { grid-area: footer; background-color: #9C27B0; color: white; }
.grid-item {
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
border-radius: 4px;
font-weight: bold;
}
该布局的结构示意图:
通过指定网格线或跨越单元格数量来控制网格项的位置和大小。
<div class="grid-container">
<div class="grid-item item-span-2-col">Item 1 (Span 2 Columns)</div>
<div class="grid-item">Item 2</div>
<div class="grid-item item-span-2-row">Item 3 (Span 2 Rows)</div>
<div class="grid-item">Item 4</div>
<div class="grid-item">Item 5</div>
<div class="grid-item item-start-2-col-span-3">Item 6 (Start Col 2, Span 3)</div>
<div class="grid-item">Item 7</div>
<div class="grid-item">Item 8</div>
<div class="grid-item">Item 9</div>
</div>
.grid-container {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 4 列 */
grid-auto-rows: minmax(80px, auto); /* 自动创建的行高度 */
gap: 10px;
border: 1px solid #ccc;
padding: 10px;
min-height: 280px;
}
.item-span-2-col {
grid-column: span 2; /* 跨越 2 列 */
}
.item-span-2-row {
grid-row: span 2; /* 跨越 2 行 */
}
.item-start-2-col-span-3 {
grid-column: 2 / span 3; /* 从第 2 列线开始,跨越 3 列 */
}
.grid-item {
background-color: #b1d4e0;
color: #2c3e50;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
border-radius: 4px;
font-weight: bold;
}
结合 grid-column 和 grid-row 实现不规则的画廊布局。
<div class="grid-container">
<div class="grid-item">Img 1</div>
<div class="grid-item">Img 2</div>
<div class="grid-item">Img 3</div>
<div class="grid-item">Img 4</div>
<div class="grid-item">Img 5</div>
</div>
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 列 */
grid-auto-rows: 120px; /* 每行高度 120px */
gap: 10px;
border: 1px solid #ccc;
padding: 10px;
min-height: 380px;
}
/* 具体的图片布局 */
.grid-item:nth-child(1) { /* 第一张图片 */
grid-column: 1 / 3; /* 从第 1 列线到第 3 列线 */
grid-row: 1 / 2; /* 从第 1 行线到第 2 行线 */
}
.grid-item:nth-child(2) { /* 第二张图片 */
grid-column: 3 / 4;
grid-row: 1 / 3;
}
.grid-item:nth-child(3) { /* 第三张图片 */
grid-column: 1 / 2;
grid-row: 2 / 4;
}
.grid-item:nth-child(4) { /* 第四张图片 */
grid-column: 2 / 3;
grid-row: 2 / 3;
}
.grid-item:nth-child(5) { /* 第五张图片 */
grid-column: 2 / 4;
grid-row: 3 / 4;
}
.grid-item {
background-color: #b1d4e0;
color: #2c3e50;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
border-radius: 4px;
font-weight: bold;
}
CSS Grid 的现代浏览器支持度非常好,主流浏览器(Chrome, Firefox, Edge, Safari)都已完全支持。您可以在 caniuse.com/#feat=css-grid 查询详细的兼容性信息。
对于需要兼容旧版浏览器的项目,可以考虑使用 Feature Queries (@supports) 进行渐进增强,或者使用 Flexbox 作为回退方案。
.container {
display: flex; /* Flexbox 回退方案 */
flex-wrap: wrap;
}
@supports (display: grid) {
.container {
display: grid; /* 如果支持 Grid,则使用 Grid */
/* ... Grid 布局代码 ... */
}
}
grid-template-areas 时,为区域使用有意义的名称,这会使您的 CSS 更易读、更易维护。CSS Grid 是现代前端布局的利器,它彻底改变了我们构建网页的方式。通过本教程的学习和案例的实践,您应该已经对 CSS Grid 的核心概念和常用技巧有了深入的理解。掌握 Grid 布局,将使您在应对各种复杂页面布局时游刃有余,大大提升开发效率和代码质量。现在,就开始您的 Grid 布局之旅吧!