CSS Grid 布局深度掌握

您好!作为一名资深前端架构师,我将为您系统地讲解 CSS Grid 布局,并提供丰富的代码示例,帮助您从入门到精通,深度掌握这一强大的布局工具。

什么是 CSS Grid 布局?

CSS Grid 布局(或称 CSS 网格布局)是一种基于网格的二维布局系统。它能够将页面划分为行(rows)和列(columns),然后将元素放置在这些网格单元中。与 Flexbox (一维布局)不同,Grid 布局能够同时控制行和列,这使得它在构建复杂页面结构时表现出无与伦比的优势。

Grid 容器与 Grid 项

在 Grid 布局中,有两个核心概念:

graph TD A[HTML 结构] --> B{display: grid}; B --> C[Grid 容器]; C --> D[Grid 项 1]; C --> E[Grid 项 2]; C --> F[Grid 项 3]; D --> G[网格单元]; E --> G; F --> G; G --> H[二维布局]; H --> I[复杂布局轻松实现];

Grid 容器属性

1. 定义网格:`grid-template-columns` 和 `grid-template-rows`

这两个属性用于显式定义网格的列和行。它们接受一系列值,每个值代表一列或一行的大小。

单位介绍:

示例 1: 基本网格定义

定义三列等宽,两行固定高度的网格。

.grid-container.example-1 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr; /* 三列,各占1份可用空间 */
    grid-template-rows: 100px 100px;    /* 两行,各高100px */
}
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6

示例 2: `repeat()` 函数

`repeat()` 函数可以简化重复的列或行定义。

.grid-container.example-2 {
    display: grid;
    grid-template-columns: repeat(3, 1fr); /* 等同于 1fr 1fr 1fr */
    grid-template-rows: repeat(2, 100px);   /* 等同于 100px 100px */
    gap: 20px; /* 列间距和行间距 */
}
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6

示例 3: `minmax()` 函数与混合单位

实现灵活的列宽:第一列固定 100px,第二列最小 1fr,第三列最小 2fr。

.grid-container.example-3 {
    display: grid;
    grid-template-columns: 100px minmax(100px, 1fr) 2fr; /* 混合单位 */
    grid-template-rows: auto auto; /* 行高自适应内容 */
    gap: 15px;
}
导航
主内容区
侧边栏
底部导航
更多内容
广告

示例 4: 自动填充与自适应:`auto-fill` / `auto-fit` 和 `minmax()`

这是构建响应式网格布局的关键。`auto-fill` 会尽可能多地填充列,即使没有足够的内容;`auto-fit` 则在内容不足时折叠空列。

.grid-container.example-4 {
    display: grid;
    /* 自动填充列,每列最小150px,最大1fr */
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
}
响应式 Item 1
响应式 Item 2
响应式 Item 3
响应式 Item 4
响应式 Item 5
响应式 Item 6

当屏幕宽度改变时,`repeat(auto-fit, minmax(150px, 1fr))` 会自动调整列的数量,确保每列至少有 150px 宽,并且均匀分配剩余空间。

2. 网格间距:`gap`, `row-gap`, `column-gap`

`gap` 是 `row-gap` 和 `column-gap` 的简写。用于设置网格项之间的间距。

.grid-container {
    gap: 20px; /* 行和列间距都是 20px */
    /* 等同于 */
    /* row-gap: 20px; */
    /* column-gap: 20px; */

    /* 或者设置不同间距 */
    /* gap: 10px 20px;  行间距 10px,列间距 20px */
}

Grid 项属性

1. 精准定位:`grid-column`, `grid-row` (`start` / `end` / `span`)

这些属性用于精确控制网格项在网格中的位置和占据的范围。

示例 5: 跨行跨列布局

构建一个常见的页面布局,包含页头、侧边栏、主内容和页脚。

.grid-container.example-5 {
    display: grid;
    grid-template-columns: 1fr 2fr; /* 两列,第二列是第一列的两倍宽 */
    grid-template-rows: auto 150px auto; /* 三行:自动高、150px、自动高 */
    gap: 10px;
}
.grid-container.example-5 .item-header {
    grid-column: 1 / span 2; /* 从第1列线开始,跨越2列 */
    background-color: #e74c3c;
}
.grid-container.example-5 .item-sidebar {
    grid-row: 2 / span 2; /* 从第2行线开始,跨越2行 */
    background-color: #f1c40f;
}
.grid-container.example-5 .item-main {
    grid-column: 2 / 3; /* 从第2列线到第3列线 */
    grid-row: 2 / 3;     /* 从第2行线到第3行线 */
    background-color: #2ecc71;
}
.grid-container.example-5 .item-footer {
    grid-column: 1 / span 2;
    background-color: #9b59b6;
}
Header
Sidebar (横跨2行)
Main Content

2. 区域命名:`grid-template-areas`

通过为网格区域命名,可以更直观地进行布局,特别适合复杂布局的可读性和维护性。

示例 6: 使用 `grid-template-areas` 构建圣杯布局

.grid-container.example-6 {
    display: grid;
    grid-template-areas:
        "header header header" /* 第一行全部是 header 区域 */
        "nav    main   aside"  /* 第二行是 nav, main, aside 区域 */
        "footer footer footer"; /* 第三行全部是 footer 区域 */
    grid-template-columns: 150px 1fr 200px; /* 定义三列宽度 */
    grid-template-rows: auto 1fr auto;      /* 定义三行高度 */
    min-height: 400px; /* 容器需要高度才能体现 1fr 的效果 */
    gap: 10px;
}
.grid-container.example-6 .item-header { grid-area: header; }
.grid-container.example-6 .item-nav    { grid-area: nav; }
.grid-container.example-6 .item-main   { grid-area: main; }
.grid-container.example-6 .item-aside  { grid-area: aside; }
.grid-container.example-6 .item-footer { grid-area: footer; }
Header
Navigation
Main Content Area
Aside

此示例完美展示了如何利用 `grid-template-areas` 轻松实现传统的圣杯布局,并且具有出色的可读性和可维护性。

Grid 容器的对齐属性

Grid 布局提供了强大的对齐能力,可以对网格项(内容)以及网格轨道(行/列)进行对齐。

1. 对齐网格项内容:`justify-items`, `align-items`, `place-items`

示例 7: 居中网格项内容

.grid-container.example-7 {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: 100px 100px;
    justify-items: center; /* 水平居中每个网格项的内容 */
    align-items: center;   /* 垂直居中每个网格项的内容 */
    /* place-items: center center; 简写 */
}
Center
Center
Center
Center
Center
Center

2. 对齐网格轨道:`justify-content`, `align-content`, `place-content`

这些属性用于当网格容器有额外空间时,如何分配这些空间来对齐整个网格。

示例 8: 对齐网格轨道

.grid-container.example-8 {
    display: grid;
    grid-template-columns: repeat(3, 80px); /* 固定列宽,制造额外空间 */
    grid-template-rows: repeat(2, 80px);    /* 固定行高,制造额外空间 */
    justify-content: space-around; /* 网格轨道在容器内平均分布,两边留有间距 */
    align-content: space-between;  /* 网格行在容器内平均分布,首尾贴边 */
    height: 300px; /* 容器需要有足够的高度来体现 align-content */
}
1
2
3
4
5
6

自动放置与流向:`grid-auto-flow`

当网格项没有明确指定位置时,浏览器会根据 `grid-auto-flow` 的设置自动放置它们。
可选值:`row` (默认), `column`, `dense` (与 `row` 或 `column` 结合使用)

示例 9: `grid-auto-flow: row dense`

.grid-container.example-9 {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-flow: row dense; /* 优先按行填充,并尝试紧密打包 */
    gap: 10px;
    min-height: 300px;
}
.grid-container.example-9 .item-span-2-col {
    grid-column: span 2; /* 跨两列 */
    background-color: #e67e22;
}
.grid-container.example-9 .item-span-2-row {
    grid-row: span 2; /* 跨两行 */
    background-color: #1abc9c;
}
1
2
3 (跨2列)
4
5 (跨2行)
6
7
8

注意观察 Item 3 和 Item 5 跨越单元格后,`dense` 如何尝试填充留下的空白区域。

Grid 的层叠上下文与 z-index

Grid 项在网格中默认是按照文档流顺序堆叠的。当多个网格项重叠时(例如通过 `grid-column` 或 `grid-row` 设置重叠),可以使用 `z-index` 来控制它们的堆叠顺序。Grid 容器会建立一个新的层叠上下文。

Grid 与响应式设计

Grid 布局天生为响应式设计而生。结合媒体查询,可以轻松实现不同屏幕尺寸下的布局调整。

在上述示例 6 的 CSS 中,我已经添加了简单的响应式媒体查询,您可以通过调整浏览器窗口大小来观察其效果。

总结与最佳实践

希望这份深度教程能帮助您全面掌握 CSS Grid 布局。它是构建现代 Web 界面不可或缺的利器,祝您在前端开发中取得更大成就!