WinddSnow

CSS-Grid-Layout-Part2-Item-Placement-and-Advanced

字数统计: 3.3k阅读时长: 14 min
2026/07/29

第29课:Grid 网格布局(下)——项目定位、网格区域命名、auto-fit vs auto-fill

上一节课我们学习了 Grid 容器属性,定义了网格的轨道结构与间距。本节课将聚焦于 Grid 项目自身的属性——如何将项目精确地放置在网格单元格中、跨越多个轨道、甚至完全脱离自动流放置。我们还会深入对比 auto-fitauto-fill 的细微差异,并学习命名网格区域这一高级技巧。掌握这些能力后,你将能够构建任何你能想到的二维布局。


1. 基于网格线的项目定位:grid-columngrid-row

每条网格线都有一个数字索引,从 1 开始。列线从左到右编号,行线从上到下编号。也可以使用显式命名的网格线(见第 28 课)。

1.1 grid-column-startgrid-column-end 及其简写

这两个属性定义项目起始于哪条列线结束于哪条列线

1
2
3
4
.item {
grid-column-start: 2; /* 从第 2 条列线开始 */
grid-column-end: 4; /* 到第 4 条列线结束(占据第 2、3 列) */
}

简写grid-column: <start> / <end>

1
2
3
.item {
grid-column: 2 / 4; /* 同上 */
}

1.2 grid-row-startgrid-row-end 及其简写

1
2
3
.item {
grid-row: 1 / 3; /* 从第 1 条行线到第 3 条行线,占据第 1、2 行 */
}

1.3 span 关键字:跨越的轨道数

不必记住精确的线号,可以告诉浏览器“从当前位置跨越 N 个轨道”。

1
2
3
4
.item {
grid-column: 2 / span 2; /* 从第 2 条列线开始,跨越 2 列 */
grid-row: 1 / span 3; /* 从第 1 条行线开始,跨越 3 行 */
}

span 也可以用在起始位置:

1
2
3
.item {
grid-column: span 3 / -1; /* 跨越 3 列,结束于最后一条列线 */
}

1.4 负线号

可以使用 -1 表示最后一条线,-2 表示倒数第二条线,以此类推。

1
2
3
.item {
grid-column: 1 / -1; /* 从第一条线到最后一条线,占满整行 */
}

1.5 网格线定位综合示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<style>
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 100px);
gap: 10px;
}
.item1 { grid-column: 1 / 3; grid-row: 1 / 3; background: #e74c3c; }
.item2 { grid-column: 3 / 5; grid-row: 1 / 2; background: #3498db; }
.item3 { grid-column: 3 / 4; grid-row: 2 / 4; background: #2ecc71; }
.item4 { grid-column: 4 / 5; grid-row: 2 / 3; background: #f39c12; }
.item5 { grid-column: 1 / 5; grid-row: 3 / 4; background: #9b59b6; }
</style>

<div class="grid">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
<div class="item4">4</div>
<div class="item5">5</div>
</div>

此示例创建了一个杂志封面式的混合布局,项目尺寸各不相同,完全由网格线定位。


2. grid-area:语法糖与区域命名

grid-area 有两种完全不同的用途。

2.1 作为 grid-row + grid-column 的终极简写

语法:grid-area: <row-start> / <column-start> / <row-end> / <column-end>

1
2
3
4
5
6
7
8
9
.item {
grid-area: 1 / 2 / 3 / 4;
/* 等价于:
grid-row-start: 1;
grid-column-start: 2;
grid-row-end: 3;
grid-column-end: 4;
*/
}

顺序记忆:上、左、下、右(逆时针)。也可以用 span

1
2
3
.item {
grid-area: 1 / 2 / span 2 / span 3;
}

2.2 配合 grid-template-areas 进行语义化布局

这是 Grid 最强大的功能之一——用 ASCII 艺术般的语法直接描述布局。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.page-layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
grid-template-columns: 200px 1fr 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
1
2
3
4
5
6
<div class="page-layout">
<header class="header">头部</header>
<aside class="sidebar">侧边栏</aside>
<main class="main">主要内容</main>
<footer class="footer">页脚</footer>
</div>

规则

  • 每个区域名必须形成一个矩形(不能是 L 形或分散的块)。
  • 可以用 . 表示空单元格。
  • 区域名相同的单元格自动合并为一个区域。

3. auto-fitauto-fill 的深度对比

两者都用于 repeat() 函数中,与 minmax() 配合创建响应式网格。但它们在有剩余空间时表现不同。

3.1 auto-fill:保留空轨道

当容器宽度大于 minmax 最小值乘以可能的最大列数时,auto-fill创建尽可能多的空列轨道(即使没有足够的项目填充它们)。这些空轨道占据空间,可能导致右侧留白。

1
2
3
.grid {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

如果容器 1000px 宽,最多可以容纳 floor(1000 / 200) = 5 列。若只有 3 个项目,auto-fill 仍会生成 5 列轨道,后两列为空,占据 2 * 200px = 400px 空间。但这 400px 也会按 1fr 参与弹性分配,实际空列会扩展得比其他列更大。

3.2 auto-fit:折叠空轨道

auto-fit 同样会生成尽可能多的列轨道,但在放置完所有项目后,空的轨道会被折叠(宽度变为 0),并将释放的空间重新分配给有内容的列(因为它们也是 1fr)。

相同场景下(容器 1000px,3 个项目),auto-fit 最终只有 3 列可见,它们会拉伸填满容器,不会留下空白列。

3.3 直观对比

特性 auto-fill auto-fit
空轨道处理 保留空轨道,它们仍占据空间(并可伸缩)。 折叠空轨道,不保留空间。
视觉效果(项目少) 项目靠左,右侧有大片留白。 项目拉伸填满整行。
适用场景 需要精确的网格列数(如动态添加内容时保持列宽不变)。 卡片网格、仪表板,希望内容始终铺满。

3.4 实战建议

  • 卡片列表、商品展示:使用 auto-fit,让卡片铺满并自动换行。
  • 日历、仪表板小部件:可能更适合 auto-fill 以保持列宽一致,即使某些格子为空。

4. justify-itemsalign-items:网格项目在单元格内的对齐

这两个属性设置所有网格项目在其所在单元格内的水平与垂直对齐方式(类似于 Flexbox 的 justify-contentalign-items,但作用在网格单元格上)。

属性 方向 默认值 常用值
justify-items 行内(水平) stretch startendcenterstretch
align-items 块级(垂直) stretch startendcenterstretch
1
2
3
4
5
6
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
justify-items: center; /* 所有项目在各自单元格内水平居中 */
align-items: center; /* 垂直居中 */
}

stretch(默认值)让项目拉伸以填满单元格宽度/高度(若项目未设固定尺寸)。

4.1 单个项目的覆盖:justify-selfalign-self

若只需调整某一个项目的对齐方式,可使用对应的 -self 属性。

1
2
3
4
.special-item {
justify-self: end; /* 水平靠右 */
align-self: start; /* 垂直靠上 */
}

5. justify-contentalign-content:整个网格在容器内的对齐

当网格总尺寸小于容器尺寸时(如轨道总宽度 < 容器宽度),这些属性控制整个网格在容器内的分布位置

属性 方向 默认值 常用值
justify-content 行内(水平) start startendcenterstretchspace-betweenspace-aroundspace-evenly
align-content 块级(垂直) start 同上
1
2
3
4
5
.grid {
display: grid;
grid-template-columns: 600px; /* 单列,宽度小于容器 */
justify-content: center; /* 网格在容器内水平居中 */
}

与 Flexbox 的类比

  • justify-content / align-content:控制整个网格在容器中的位置(与 Flex 的 justify-content 作用于主轴类似,但 Grid 有二维)。
  • justify-items / align-items:控制网格项目在单元格内的位置。

6. 综合示例:仪表板页面布局

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
<style>
.dashboard {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
grid-template-columns: 240px 1fr 1fr;
grid-template-rows: 60px 1fr 50px;
min-height: 100vh;
gap: 16px;
padding: 16px;
}
.header { grid-area: header; background: #1a1a2e; color: white; display: flex; align-items: center; padding: 0 24px; border-radius: 8px; }
.sidebar { grid-area: sidebar; background: #f0f0f0; padding: 20px; border-radius: 8px; }
.main { grid-area: main; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); }
.footer { grid-area: footer; background: #1a1a2e; color: #aaa; display: flex; align-items: center; justify-content: center; border-radius: 8px; }
</style>

<div class="dashboard">
<header class="header">📊 管理仪表板</header>
<aside class="sidebar">导航菜单</aside>
<main class="main">
<h2>概览</h2>
<div class="stats" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; margin-top: 20px;">
<div style="background:#3498db; color:white; padding:16px; border-radius:8px;">销售额 ¥12,400</div>
<div style="background:#2ecc71; color:white; padding:16px; border-radius:8px;">订单 356</div>
<div style="background:#e74c3c; color:white; padding:16px; border-radius:8px;">待处理 23</div>
</div>
</main>
<footer class="footer">© 2026 Dashboard Inc.</footer>
</div>

课后练习

一、概念自测(选择题 / 填空题)

  1. (单选) grid-area: 2 / 1 / 4 / 3 的含义是?
    A. 从第 2 行线、第 1 列线开始,到第 4 行线、第 3 列线结束。
    B. 从第 1 行线、第 2 列线开始,到第 3 行线、第 4 列线结束。
    C. 占据第 2~3 行和第 1~2 列。
    D. 从第 2 列线、第 1 行线开始,跨越 4 行 3 列。

  2. (单选) 以下关于 auto-fitauto-fill 的描述,正确的是?
    A. auto-fit 会保留空轨道,auto-fill 会折叠空轨道。
    B. 两者完全相同,仅名称不同。
    C. auto-fit 折叠空轨道,auto-fill 保留空轨道。
    D. auto-fit 仅用于 grid-template-rowsauto-fill 仅用于 grid-template-columns

  3. (填空) 要设置网格容器内所有项目在其单元格中水平居中和垂直靠底部,应使用 justify-items: ______align-items: ______

  4. (多选) 以下哪些方式可以实现 Grid 项目的精确定位?
    A. grid-column: 1 / 3
    B. grid-area: 1 / 1 / 2 / 4
    C. grid-template-areas 配合 grid-area
    D. grid-auto-flow: column

二、AI 编程任务:编写面向 AI 的提示词

场景:你需要实现一个杂志风格的文章列表布局(Masonry 风格不用 JS,用 Grid 近似实现)。要求如下:

  • 整体使用 Grid 布局,4 列。
  • 第一篇文章(特色文章)占 2 列 2 行。
  • 其余文章每篇占 1 列 1 行,但通过 span 或网格线控制形成参差不齐的视觉效果(如有意让第三篇文章占 2 列)。
  • 使用网格线定位,不使用 grid-template-areas
  • 设置合适的 gap 和项目背景色以区分区块。

任务要求:请写出一段完整的中文提示词,发送给 AI,使其生成符合上述要求的 HTML + CSS 代码。提示词中需明确指定 Grid 项目定位属性、span 用法、以及整体网格定义。

三、Agent 模式下的提示词示例

你是一个资深前端开发 Agent。请使用 CSS Grid 构建一个杂志风格的文章布局组件。需要创建以下文件:

  1. index.html:包含一个网格容器 .magazine-grid,内含 7 篇示例文章(.article),每篇文章包含一张占位图片和标题。第一篇文章标记为 .article--featured
  2. styles/magazine.css:定义 .magazine-grid 为 Grid 容器,grid-template-columns: repeat(4, 1fr)gap: 16pxgrid-auto-rows: 200px.article--featured 使用 grid-column: span 2; grid-row: span 2;。其余文章按顺序放置,有意让第三篇文章使用 grid-column: span 2; 形成特殊效果。所有文章背景色 #f9f9f9,圆角,内边距。
  3. styles/global.css:引入盒模型重置、基础字体。
  4. 确保代码整洁、注释说明每一项定位的目的。在 index.html 中正确引入 CSS 文件。

课后练习答案

一、概念自测答案

  1. A

    • 解析:grid-area 顺序为 row-start / column-start / row-end / column-end。A 项描述完全正确。
  2. C

    • 解析:auto-fit 折叠空轨道,使存在列填满;auto-fill 保留空轨道,可能导致留白。
  3. centerend

    • 解析:justify-items: center 水平居中;align-items: end 垂直靠底。
  4. A、B、C

    • 解析:A 和 B 都是基于网格线的定位;C 是基于命名区域的定位。D 是自动流方向控制,不能精确定位单个项目。

二、AI 编程任务参考答案(提示词示例)

示例提示词
“请使用 CSS Grid 创建一个杂志风格的文章列表布局。要求:

  • 容器 .magazine-grid 设置 display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 200px; gap: 16px;
  • 第一篇文章 .article--featured 使用 grid-column: span 2; grid-row: span 2; 占 2 列 2 行。
  • 第三篇文章特殊处理,使用 grid-column: span 2; 占 2 列。
  • 其余文章默认占 1 列 1 行(无需额外声明)。
  • 每篇文章包含一张占位图(https://via.placeholder.com/400x200)和一个标题,背景色 #f9f9f9,圆角 8px,内边距 12px。
  • 至少提供 7 篇文章示例。直接输出完整 HTML 文件。”

三、Agent 模式下的提示词示例

(见上文 Agent 提示词部分)

CATALOG
  1. 1. 第29课:Grid 网格布局(下)——项目定位、网格区域命名、auto-fit vs auto-fill
    1. 1.1. 1. 基于网格线的项目定位:grid-column 与 grid-row
      1. 1.1.1. 1.1 grid-column-start、grid-column-end 及其简写
      2. 1.1.2. 1.2 grid-row-start、grid-row-end 及其简写
      3. 1.1.3. 1.3 span 关键字:跨越的轨道数
      4. 1.1.4. 1.4 负线号
      5. 1.1.5. 1.5 网格线定位综合示例
    2. 1.2. 2. grid-area:语法糖与区域命名
      1. 1.2.1. 2.1 作为 grid-row + grid-column 的终极简写
      2. 1.2.2. 2.2 配合 grid-template-areas 进行语义化布局
    3. 1.3. 3. auto-fit 与 auto-fill 的深度对比
      1. 1.3.1. 3.1 auto-fill:保留空轨道
      2. 1.3.2. 3.2 auto-fit:折叠空轨道
      3. 1.3.3. 3.3 直观对比
      4. 1.3.4. 3.4 实战建议
    4. 1.4. 4. justify-items 与 align-items:网格项目在单元格内的对齐
      1. 1.4.1. 4.1 单个项目的覆盖:justify-self 与 align-self
    5. 1.5. 5. justify-content 与 align-content:整个网格在容器内的对齐
    6. 1.6. 6. 综合示例:仪表板页面布局
    7. 1.7. 课后练习
      1. 1.7.1. 一、概念自测(选择题 / 填空题)
      2. 1.7.2. 二、AI 编程任务:编写面向 AI 的提示词
      3. 1.7.3. 三、Agent 模式下的提示词示例
    8. 1.8. 课后练习答案
      1. 1.8.1. 一、概念自测答案
      2. 1.8.2. 二、AI 编程任务参考答案(提示词示例)
      3. 1.8.3. 三、Agent 模式下的提示词示例