- 发布于
CSS Grid 布局完全指南:现代网页布局的终极解决方案
- 作者

- 姓名
- 全能波
- GitHub
- @weicracker
CSS Grid 布局完全指南:现代网页布局的终极解决方案
CSS Grid 是现代 CSS 中最强大的布局系统之一,它为我们提供了二维布局的完整解决方案。本文将深入探讨 Grid 布局的各个方面,帮助你掌握这个强大的工具。
Grid 布局基础概念
什么是 CSS Grid?
CSS Grid 是一个二维布局系统,允许我们同时在行和列两个维度上控制元素的位置和大小。与 Flexbox 的一维布局不同,Grid 提供了更强大的布局能力。
/* 基础 Grid 容器 */
.grid-container {
display: grid;
grid-template-columns: 200px 1fr 100px;
grid-template-rows: auto 1fr auto;
gap: 20px;
height: 100vh;
}
.header {
grid-area: 1 / 1 / 2 / 4;
}
.sidebar {
grid-area: 2 / 1 / 3 / 2;
}
.main {
grid-area: 2 / 2 / 3 / 3;
}
.aside {
grid-area: 2 / 3 / 3 / 4;
}
.footer {
grid-area: 3 / 1 / 4 / 4;
}
Grid 术语解释
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
</div>
.grid-container {
display: grid;
/* 网格轨道(Grid Tracks) */
grid-template-columns: 1fr 2fr 1fr; /* 列轨道 */
grid-template-rows: 100px auto; /* 行轨道 */
/* 网格间隙(Grid Gap) */
gap: 10px; /* 行间隙和列间隙 */
/* 或者分别设置 */
row-gap: 15px;
column-gap: 20px;
/* 网格线(Grid Lines)自动生成 */
/* 列线:1, 2, 3, 4 */
/* 行线:1, 2, 3 */
}
创建网格容器
1. 显式网格定义
/* 使用具体尺寸 */
.grid-explicit {
display: grid;
grid-template-columns: 200px 300px 200px;
grid-template-rows: 100px 200px;
}
/* 使用 fr 单位(分数单位) */
.grid-fractional {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 1:2:1 的比例 */
grid-template-rows: 100px 1fr;
}
/* 使用 repeat() 函数 */
.grid-repeat {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 等同于 1fr 1fr 1fr */
grid-template-rows: repeat(2, 100px);
}
/* 混合使用不同单位 */
.grid-mixed {
display: grid;
grid-template-columns: 200px 1fr auto;
grid-template-rows: auto 1fr 50px;
}
2. 隐式网格
.grid-implicit {
display: grid;
grid-template-columns: repeat(3, 1fr);
/* 当内容超出显式网格时,隐式网格的尺寸 */
grid-auto-rows: 100px;
grid-auto-columns: 200px;
/* 隐式网格项目的放置方向 */
grid-auto-flow: row; /* 默认值,按行填充 */
/* grid-auto-flow: column; 按列填充 */
/* grid-auto-flow: row dense; 紧密填充 */
}
网格项目定位
1. 基于网格线定位
.grid-item-1 {
/* 使用网格线编号 */
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 2;
/* 简写形式 */
grid-column: 1 / 3;
grid-row: 1 / 2;
/* 更简洁的写法 */
grid-area: 1 / 1 / 2 / 3; /* row-start / col-start / row-end / col-end */
}
.grid-item-2 {
/* 使用 span 关键字 */
grid-column: span 2; /* 跨越 2 列 */
grid-row: span 1; /* 跨越 1 行 */
}
.grid-item-3 {
/* 使用负数从末尾开始计算 */
grid-column: 1 / -1; /* 从第一列到最后一列 */
grid-row: 2 / -1; /* 从第二行到最后一行 */
}
2. 命名网格线
.grid-named-lines {
display: grid;
grid-template-columns:
[sidebar-start] 200px
[sidebar-end main-start] 1fr
[main-end aside-start] 200px
[aside-end];
grid-template-rows:
[header-start] 80px
[header-end content-start] 1fr
[content-end footer-start] 60px
[footer-end];
}
.header {
grid-column: sidebar-start / aside-end;
grid-row: header-start / header-end;
}
.sidebar {
grid-column: sidebar-start / sidebar-end;
grid-row: content-start / content-end;
}
.main {
grid-column: main-start / main-end;
grid-row: content-start / content-end;
}
3. 网格区域模板
.grid-template-areas {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 80px 1fr 60px;
grid-template-areas:
'header header header'
'sidebar main aside'
'footer footer footer';
gap: 20px;
}
.header {
grid-area: header;
}
.sidebar {
grid-area: sidebar;
}
.main {
grid-area: main;
}
.aside {
grid-area: aside;
}
.footer {
grid-area: footer;
}
响应式网格布局
1. 自适应列数
/* 自动适应的网格 */
.auto-fit-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
/* auto-fill vs auto-fit */
.auto-fill-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 15px;
}
.auto-fit-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
}
2. 媒体查询结合 Grid
.responsive-grid {
display: grid;
gap: 20px;
/* 移动端:单列布局 */
grid-template-columns: 1fr;
grid-template-areas:
'header'
'main'
'sidebar'
'footer';
}
@media (min-width: 768px) {
.responsive-grid {
/* 平板:两列布局 */
grid-template-columns: 200px 1fr;
grid-template-areas:
'header header'
'sidebar main'
'footer footer';
}
}
@media (min-width: 1024px) {
.responsive-grid {
/* 桌面:三列布局 */
grid-template-columns: 200px 1fr 200px;
grid-template-areas:
'header header header'
'sidebar main aside'
'footer footer footer';
}
}
高级 Grid 技巧
1. 网格对齐
.grid-alignment {
display: grid;
grid-template-columns: repeat(3, 200px);
grid-template-rows: repeat(3, 100px);
gap: 10px;
height: 500px;
/* 整个网格在容器中的对齐 */
justify-content: center; /* 水平对齐:start | end | center | stretch | space-around | space-between | space-evenly */
align-content: center; /* 垂直对齐:start | end | center | stretch | space-around | space-between | space-evenly */
/* 网格项目在网格区域中的对齐 */
justify-items: center; /* 水平对齐:start | end | center | stretch */
align-items: center; /* 垂直对齐:start | end | center | stretch */
}
/* 单个网格项目的对齐 */
.grid-item-special {
justify-self: end; /* 覆盖 justify-items */
align-self: start; /* 覆盖 align-items */
}
2. 嵌套网格
.outer-grid {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 20px;
}
.nested-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(3, 80px);
gap: 10px;
}
3. 子网格(Subgrid)
/* 注意:subgrid 支持有限,主要在 Firefox 中 */
.parent-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 100px);
gap: 20px;
}
.subgrid-item {
grid-column: 2 / 4;
grid-row: 1 / 3;
display: grid;
grid-template-columns: subgrid; /* 继承父网格的列 */
grid-template-rows: subgrid; /* 继承父网格的行 */
}
实际应用案例
1. 卡片网格布局
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 24px;
padding: 24px;
}
.card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: transform 0.2s ease;
}
.card:hover {
transform: translateY(-4px);
}
.card-image {
width: 100%;
height: 200px;
object-fit: cover;
}
.card-content {
padding: 20px;
}
/* 特殊卡片占据更多空间 */
.card.featured {
grid-column: span 2;
}
@media (max-width: 768px) {
.card.featured {
grid-column: span 1; /* 移动端取消跨列 */
}
}
2. 复杂的杂志布局
.magazine-layout {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: repeat(8, 100px);
gap: 16px;
max-width: 1200px;
margin: 0 auto;
}
.hero-article {
grid-column: 1 / 8;
grid-row: 1 / 5;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 32px;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.side-article-1 {
grid-column: 8 / 13;
grid-row: 1 / 3;
}
.side-article-2 {
grid-column: 8 / 13;
grid-row: 3 / 5;
}
.bottom-article-1 {
grid-column: 1 / 5;
grid-row: 5 / 7;
}
.bottom-article-2 {
grid-column: 5 / 9;
grid-row: 5 / 7;
}
.bottom-article-3 {
grid-column: 9 / 13;
grid-row: 5 / 7;
}
.ad-space {
grid-column: 1 / 13;
grid-row: 7 / 9;
background: #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
}
3. 仪表板布局
.dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
grid-template-areas:
'sidebar header'
'sidebar main';
height: 100vh;
gap: 0;
}
.dashboard-header {
grid-area: header;
background: white;
border-bottom: 1px solid #e0e0e0;
display: flex;
align-items: center;
padding: 0 24px;
}
.dashboard-sidebar {
grid-area: sidebar;
background: #2c3e50;
color: white;
padding: 24px 0;
}
.dashboard-main {
grid-area: main;
background: #f8f9fa;
padding: 24px;
overflow-y: auto;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-auto-rows: min-content;
gap: 24px;
align-content: start;
}
.widget {
background: white;
border-radius: 8px;
padding: 24px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.widget.large {
grid-column: span 2;
}
.widget.tall {
grid-row: span 2;
}
/* 响应式调整 */
@media (max-width: 768px) {
.dashboard {
grid-template-columns: 1fr;
grid-template-rows: 60px auto 1fr;
grid-template-areas:
'header'
'sidebar'
'main';
}
.dashboard-sidebar {
max-height: 200px;
overflow-y: auto;
}
.widget.large,
.widget.tall {
grid-column: span 1;
grid-row: span 1;
}
}
Grid 与 Flexbox 的结合
.hybrid-layout {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 24px;
background: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.main-content {
display: grid;
grid-template-columns: 250px 1fr;
gap: 24px;
padding: 24px;
}
.content-area {
display: flex;
flex-direction: column;
gap: 24px;
}
.article-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
.footer {
display: flex;
justify-content: center;
align-items: center;
padding: 24px;
background: #f8f9fa;
border-top: 1px solid #e0e0e0;
}
性能优化建议
1. 避免不必要的重排
/* ✅ 好的做法:使用 transform 而不是改变 grid 属性 */
.grid-item {
transition: transform 0.3s ease;
}
.grid-item:hover {
transform: scale(1.05);
}
/* ❌ 避免:频繁改变 grid 属性 */
.grid-item:hover {
grid-column: span 2; /* 会导致整个网格重新计算 */
}
2. 合理使用 will-change
.animated-grid-item {
will-change: transform;
transition: transform 0.3s ease;
}
.animated-grid-item:hover {
transform: translateY(-8px);
}
/* 动画结束后移除 will-change */
.animated-grid-item.animation-complete {
will-change: auto;
}
总结
CSS Grid 为现代网页布局提供了强大而灵活的解决方案:
- 二维布局:同时控制行和列
- 灵活的尺寸单位:fr、auto、minmax() 等
- 强大的对齐能力:多种对齐选项
- 响应式友好:auto-fit、auto-fill 等特性
- 语义化布局:grid-template-areas 提供直观的布局定义
掌握 CSS Grid,你就能创建出复杂而优雅的网页布局!
CSS Grid 是现代前端开发的必备技能,值得深入学习和实践。