CSS Grid 是一个二维布局系统,专门用于解决复杂的网页布局问题。相比 Flexbox(一维布局),Grid 能够同时处理行和列,为网页设计提供了前所未有的灵活性。
Grid 基础概念#
1. Grid 容器和项目#
1
2
3
4
5
6
7
8
9
10
11
| /* 定义 Grid 容器 */
.container {
display: grid;
/* 或者 */
display: inline-grid;
}
/* Grid 项目会自动成为子元素 */
.container > div {
/* 这些 div 自动成为 Grid 项目 */
}
|
2. 网格线和轨道#
1
2
3
4
5
6
| .container {
display: grid;
grid-template-columns: 100px 200px 100px; /* 3列 */
grid-template-rows: 50px 100px; /* 2行 */
gap: 10px; /* 网格间距 */
}
|
定义网格结构#
1. 固定和弹性网格#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| /* 固定尺寸 */
.grid-fixed {
display: grid;
grid-template-columns: 200px 1fr 200px; /* 1fr = 1个弹性单位 */
grid-template-rows: 60px 1fr 40px;
height: 100vh;
}
/* 响应式网格 */
.grid-responsive {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
/* 混合单位 */
.grid-mixed {
display: grid;
grid-template-columns: 200px 1fr 100px;
grid-template-rows: auto 1fr auto;
}
|
2. 命名网格线#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| .container {
display: grid;
grid-template-columns:
[sidebar-start] 200px
[main-start] 1fr
[main-end sidebar-end];
grid-template-rows:
[header-start] 60px
[main-start] 1fr
[main-end footer-start] 40px
[footer-end];
}
/* 使用命名网格线放置项目 */
.header {
grid-column: sidebar-start / sidebar-end;
grid-row: header-start;
}
|
3. 命名网格区域#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| .container {
display: grid;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 60px 1fr 40px;
gap: 10px;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
|
Grid 项目定位#
1. 基于网格线定位#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| .item {
/* 从第2条列线到第4条列线 */
grid-column: 2 / 4;
/* 从第1条行线到第3条行线 */
grid-row: 1 / 3;
}
/* 使用 span 关键字 */
.item-span {
/* 占据2列 */
grid-column: span 2;
/* 占据3行 */
grid-row: span 3;
}
/* 更简洁的写法 */
.item-compact {
/* 从第2列开始,占据2列 */
grid-column: 2 / span 2;
}
|
2. 基于区域定位#
1
2
3
4
5
6
7
8
9
| .item-area {
grid-area: 2 / 2 / 4 / 4;
/* 等同于:
grid-row-start: 2;
grid-column-start: 2;
grid-row-end: 4;
grid-column-end: 4;
*/
}
|
3. 自动定位#
1
2
3
4
5
6
7
8
9
| .container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: row; /* 或 column */
}
.item {
/* Grid 会自动放置项目 */
}
|
高级 Grid 特性#
1. 自动网格#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| .container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px; /* 自动创建的行高 */
grid-auto-flow: dense; /* 密集填充算法 */
}
/* 定义自动列 */
.auto-columns {
display: grid;
grid-template-rows: repeat(3, 100px);
grid-auto-columns: 150px; /* 自动创建的列宽 */
grid-auto-flow: column; /* 按列填充 */
}
|
2. 子网格(Subgrid)#
1
2
3
4
5
6
7
8
9
10
11
12
| .parent {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
}
.child {
display: grid;
grid-template-columns: subgrid; /* 继承父容器的列定义 */
grid-column: span 2;
gap: inherit; /* 继承父容器的间距 */
}
|
3. 网格对齐#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| .container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
height: 400px;
/* 整个网格在容器中的对齐 */
justify-content: center; /* 水平对齐 */
align-content: center; /* 垂直对齐 */
/* 所有项目的默认对齐 */
justify-items: stretch; /* 项目水平拉伸 */
align-items: stretch; /* 项目垂直拉伸 */
}
/* 单个项目的对齐 */
.item {
justify-self: start; /* 覆盖默认的 justify-items */
align-self: end; /* 覆盖默认的 align-items */
}
|
实际应用示例#
1. 圣杯布局#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| .holy-grail {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 60px 1fr 40px;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
min-height: 100vh;
gap: 10px;
}
.header { grid-area: header; background: #e3f2fd; }
.nav { grid-area: nav; background: #f3e5f5; }
.main { grid-area: main; background: #e8f5e8; }
.aside { grid-area: aside; background: #fff3e0; }
.footer { grid-area: footer; background: #fce4ec; }
/* 响应式调整 */
@media (max-width: 768px) {
.holy-grail {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
}
}
|
2. 卡片布局#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| .card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
padding: 20px;
}
.card {
display: grid;
grid-template-rows: auto 1fr auto;
gap: 15px;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.card-image {
width: 100%;
height: 200px;
object-fit: cover;
border-radius: 4px;
}
|
3. 仪表板布局#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| .dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
grid-template-areas:
"sidebar header"
"sidebar main";
height: 100vh;
gap: 1px;
background: #e0e0e0;
}
.sidebar {
grid-area: sidebar;
background: white;
padding: 20px;
}
.header {
grid-area: header;
background: white;
display: flex;
align-items: center;
padding: 0 20px;
}
.main {
grid-area: main;
background: #f5f5f5;
padding: 20px;
overflow-y: auto;
}
/* 主内容区域的网格 */
.widgets {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
.widget {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
|
与 Flexbox 的配合使用#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| .container {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 20px;
}
.sidebar {
display: flex;
flex-direction: column;
gap: 10px;
}
.main {
display: flex;
flex-direction: column;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
.content {
flex: 1;
display: flex;
flex-direction: column;
}
|
性能优化技巧#
1. 避免频繁重排#
1
2
3
4
5
6
7
| .container {
display: grid;
/* 使用固定值减少重排 */
grid-template-columns: 200px 1fr 200px;
/* 使用 contain 属性优化 */
contain: layout;
}
|
2. 合理使用 minmax()#
1
2
3
4
5
6
7
8
| /* 更好的响应式设计 */
.responsive-grid {
display: grid;
grid-template-columns: repeat(
auto-fill,
minmax(min(100%, 300px), 1fr)
);
}
|
浏览器兼容性#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| /* 带前缀的写法 */
.grid {
display: -ms-grid;
display: grid;
-ms-grid-columns: 200px 1fr 200px;
grid-template-columns: 200px 1fr 200px;
}
/* 使用 @supports */
@supports (display: grid) {
.modern-layout {
display: grid;
/* 现代 Grid 布局 */
}
}
|
调试技巧#
1. 可视化网格#
1
2
3
4
5
6
7
8
9
10
11
12
13
| .container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
/* 开发时添加的调试样式 */
.container.debug {
background-image:
linear-gradient(rgba(255,0,0,0.1) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,0,0,0.1) 1px, transparent 1px);
background-size: 50px 50px;
}
|
2. 使用浏览器开发工具#
1
2
3
4
| /* 在 Chrome DevTools 中 */
/* 选择 Grid 容器 */
/* 在 Styles 面板中点击 Grid 图标 */
/* 可以可视化网格线和网格区域 */
|
CSS Grid 是一个强大的布局工具,它提供了:
- 二维布局能力:同时控制行和列
- 灵活的尺寸控制:固定、弹性、自动尺寸
- 直观的命名系统:网格线命名、区域命名
- 优秀的响应式支持:auto-fit、auto-fill、minmax()
- 与其他 CSS 特性的良好集成:Flexbox、自定义属性等
掌握 Grid 布局将大大提升你的网页布局能力,让复杂的布局变得简单直观。
相关工具: