CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
HTML 与 CSS 基础/课时/Grid 布局
RawBlame
课时目录12 节

HTML 与 CSS 基础

  1. 01网页如何工作
  2. 02HTML 文档结构
  3. 03文本、链接与媒体
  4. 04HTML 表单
  5. 05语义化与可访问性
  6. 06CSS 选择器与层叠
  7. 07盒模型与布局流
  8. 08Flexbox 布局
  9. 09Grid 布局
  10. 10响应式设计
  11. 11综合练习:静态课程页
  12. 12框架与下一步

Grid 布局

网格轨道、区域、页面骨架。

35 分钟

CSS Grid 网格布局

这一课你将能做到

  1. 使用 CSS Grid 构建二维网格布局,定义行、列和间距
  2. 使用 grid-template-areas 以可视化方式命名和放置页面区域
  3. 结合 minmax()、auto-fill、auto-fit 实现真正的响应式卡片网格,无需媒体查询

为什么要学

Flexbox 解决了一维布局(一行或一列),但现代网页本质上是二维的:整体页面有头部、侧边栏、主内容、页脚;课程列表有行有列;仪表板有多个大小不一的卡片。在 Grid 出现之前,开发者用浮动、定位和负 margin 模拟网格,代码脆弱且难以维护。

CSS Grid 是第一个专门为「二维布局」设计的 CSS 模块。CodeForge 的课程卡片矩阵、学习路线图的阶梯式布局、仪表盘的多卡片面板,都是 Grid 的天然应用场景。Grid 让「把这块区域放在第 2 行第 3 列」变成一句声明,而不是一堆计算和 hack。

先建立图像

一个 3×3 的 Grid 网格:

+----------+----------+----------+
|  1,1     |  1,2     |  1,3     |  ← 行(row)
+----------+----------+----------+
|  2,1     |  2,2     |  2,3     |
+----------+----------+----------+
|  3,1     |  3,2     |  3,3     |
+----------+----------+----------+
     ↑          ↑          ↑
   列1        列2        列3      ← 列(column)

Grid 线(grid line):行和列的边界线,从 1 开始编号
Grid 轨道(grid track):两条相邻线之间的空间(一行或一列)
Grid 单元格(grid cell):行和列交叉的最小单位
Grid 区域(grid area):一个或多个单元格组成的矩形区域

跟着做

步骤 1:创建基础网格

创建 grid.html,核心 CSS 如下:

:root { --primary: #2563eb; --surface: #fff; --border: #e2e8f0; --text: #0f172a; }
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: system-ui, sans-serif; padding: 2rem; background: #f1f5f9; color: var(--text); }
.grid-container { display: grid; gap: 1rem; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 1rem; }
.grid-item { background: var(--primary); color: white; padding: 1.5rem; border-radius: 8px; display: grid; place-items: center; font-weight: 500; }

页面骨架与之前课程相同,在 <body> 中放入以下三个演示区块:

<!-- 1. 三列等宽网格 -->
<div class="grid-container" style="grid-template-columns: 1fr 1fr 1fr;">
  <div class="grid-item">A</div><div class="grid-item">B</div><div class="grid-item">C</div>
  <div class="grid-item">D</div><div class="grid-item">E</div><div class="grid-item">F</div>
</div>

<!-- 2. 固定宽度 + 自适应 -->
<div class="grid-container" style="grid-template-columns: 200px 1fr 200px;">
  <div class="grid-item">侧边栏 200px</div>
  <div class="grid-item">主内容自适应</div>
  <div class="grid-item">侧边栏 200px</div>
</div>

<!-- 3. 响应式自动填充 -->
<div class="grid-container" style="grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));">
  <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 class="grid-item">课程 5</div>
</div>

打开页面,调整浏览器窗口宽度,观察「响应式自动填充」一节:当窗口变窄时,卡片自动从多列变为少列,无需任何媒体查询。repeat(auto-fill, minmax(200px, 1fr)) 的含义是:每列至少 200px,最多均分剩余空间,能放几列放几列。

步骤 2:使用 grid-template-areas 命名区域

<div class="grid-container" style="
  grid-template-columns: 200px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    'header header'
    'sidebar main'
    'footer footer';
  min-height: 400px;
">
  <div class="grid-item" style="grid-area: header;">Header</div>
  <div class="grid-item" style="grid-area: sidebar;">Sidebar</div>
  <div class="grid-item" style="grid-area: main;">Main Content</div>
  <div class="grid-item" style="grid-area: footer;">Footer</div>
</div>

grid-template-areas 用 ASCII 艺术的方式直观定义布局结构。每个字符串代表一行,字符串中的每个词代表一个命名区域。. 表示空单元格。这是构建页面骨架最可读的方式。

步骤 3:控制项目位置与跨度

<div class="grid-container" style="grid-template-columns: repeat(4, 1fr);">
  <div class="grid-item" style="grid-column: span 2;">跨 2 列</div>
  <div class="grid-item">1 列</div>
  <div class="grid-item">1 列</div>
  <div class="grid-item" style="grid-column: span 2; grid-row: span 2;">跨 2×2</div>
  <div class="grid-item">1 列</div>
  <div class="grid-item">1 列</div>
  <div class="grid-item" style="grid-column: 2 / 4;">从第 2 列线到第 4 列线</div>
</div>
  • grid-column: span 2:项目占 2 列宽度
  • grid-row: span 2:项目占 2 行高度
  • grid-column: 2 / 4:从第 2 条列线开始到第 4 条列线结束(即占第 2、3 列)

步骤 4:对齐控制

<div class="grid-container" style="
  grid-template-columns: repeat(3, 100px);
  justify-content: center;
  height: 200px;
  align-content: center;
">
  <div class="grid-item">A</div>
  <div class="grid-item">B</div>
  <div class="grid-item">C</div>
</div>
  • justify-items / align-items:控制单元格内项目的对齐(类比 Flex 的 align-items)
  • justify-content / align-content:控制整个网格在容器内的对齐(当网格总尺寸小于容器时)
  • place-items: center 是 align-items: center; justify-items: center 的缩写

步骤 5:实战——CodeForge 课程卡片网格

.course-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
}
.course-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.course-card .cover {
  height: 140px;
  background: linear-gradient(135deg, var(--primary), #7c3aed);
  display: grid;
  place-items: center;
  color: white;
  font-weight: 600;
}
.course-card .body { padding: 1.25rem; flex: 1; display: flex; flex-direction: column; }
.course-card h3 { margin: 0 0 0.5rem; font-size: 1.125rem; }
.course-card p { margin: 0 0 1rem; color: #64748b; font-size: 0.9375rem; flex: 1; }
.course-card .footer { display: flex; justify-content: space-between; align-items: center; }
<div class="course-grid">
  <article class="course-card">
    <div class="cover">课程封面</div>
    <div class="body">
      <h3>HTML/CSS 基础</h3>
      <p>掌握语义化标签、盒模型、Flexbox 与 Grid 布局。</p>
      <div class="footer"><span style="color:var(--primary);font-weight:600;">免费</span><button>开始学习</button></div>
    </div>
  </article>
  <!-- 更多卡片... -->
</div>

注意这个卡片内部用了 Flexbox(flex-direction: column + flex: 1 让按钮始终贴底),而卡片之间的排列用 Grid。这是典型的「Grid 管宏观,Flex 管微观」的组合模式。

讲清楚要点

  1. Grid 是二维布局系统:与 Flexbox 的一维模型不同,Grid 同时控制行和列。你可以精确地说「这个元素放在第 2 行第 3 列」,而不必关心 HTML 源码顺序。这是布局思维的根本转变。

  2. fr 单位是 Grid 的灵魂:fr(fraction,剩余空间份数)让列宽按比例分配,自动适应容器大小。1fr 2fr 1fr 表示三列按 1:2:1 分配。fr 与 minmax() 结合可实现既灵活又有下限的响应式轨道。

  3. grid-template-areas 提升可维护性:对于整体页面布局,用命名区域比数行列号更直观。修改布局时只需调整 ASCII 图,不用重新计算每个项目的 grid-column 和 grid-row。配合媒体查询,可以轻松实现「移动端单列,桌面端多列」。

  4. 自动放置算法:未显式指定位置的项目,Grid 会按源码顺序自动填充空白单元格。grid-auto-flow: dense 可以让后续项目回填前面留下的空隙,适合卡片大小不一的 masonry 式布局。

  5. auto-fill vs auto-fit:auto-fill 在轨道不足时保留空轨道(可能产生空白列);auto-fit 会折叠空轨道,让现有项目拉伸占满。响应式卡片网格通常用 auto-fit。

  6. Grid 与 Flex 的边界:Grid 擅长「由外向内」的布局——先定义网格骨架,再把内容放进去。Flex 擅长「由内向外」的布局——内容决定尺寸,排列随内容变化。两者互补,不是替代关系。

你可能会懵的地方

  • 「Grid 和 Flexbox 到底哪个更好?」 不是竞争关系。Grid 管二维页面骨架,Flex 管一维组件内部。一个页面通常外层用 Grid 划分区域,区域内用 Flex 排列元素。例如:Grid 定义「侧边栏 + 主内容」,主内容内部的按钮组用 Flex 排列。

  • 「grid-template-columns: repeat(3, 1fr) 和 grid-template-columns: 1fr 1fr 1fr 有区别吗?」 功能上完全一样。repeat(3, 1fr) 是简写,避免重复书写。当列数很多或模式复杂时(如 repeat(3, 1fr 2fr) 表示 6 列:1fr, 2fr, 1fr, 2fr, 1fr, 2fr),repeat() 的可读性优势明显。

  • 「为什么我的 Grid 项目没有按预期位置放置?」 检查是否显式指定了 grid-column 或 grid-row。如果没有,Grid 的自动放置算法会按源码顺序填充。如果项目有 span 导致无法放入当前行,算法会跳到下一行,可能留下空隙。用 grid-auto-flow: dense 可让后续项目回填空隙。

  • 「Grid 能做瀑布流(Masonry)吗?」 纯 CSS Grid 的 grid-auto-flow: dense 可以近似,但列高由整行最高项目决定,不是真正的 Masonry。真正的 Masonry 需要 grid-template-rows: masonry(Firefox 实验性支持)或 JavaScript 库。对于等高卡片,Grid 完全够用。

  • 「Grid 的浏览器兼容性如何?」 现代浏览器(Chrome、Firefox、Safari、Edge)自 2017 年起全面支持 Grid。IE11 有旧版 Grid 规范(-ms- 前缀),但语法差异大,不建议为 IE11 使用 Grid。如果需要兼容旧浏览器,可以用 @supports 查询提供 Flexbox 回退。

错法对照

错法问题正解
用 Grid 做简单的水平按钮组大材小用,代码复杂用 Flexbox
用浮动或定位模拟网格脆弱,需要清除浮动,响应式困难用 Grid 的 grid-template-columns
硬编码列数,窗口变窄时溢出需要大量媒体查询用 repeat(auto-fit, minmax(250px, 1fr))
给每个项目写 grid-column: 1 / 2 等精确位置维护困难,插入新项目时要重新编号用 grid-template-areas 或让自动放置算法处理
忽略 gap 用 margin 做间距边缘项目需要特殊处理用容器的 gap 属性
在 Grid 项目中继续用浮动破坏 Grid 布局,产生意外结果Grid 项目内部用正常流、Flex 或嵌套 Grid

卡点急救

  1. Grid 项目之间没有间距:检查是否给容器设置了 gap。Grid 的 gap 同时作用于行和列(row-gap 和 column-gap 的缩写)。旧代码可能用 grid-gap,现代浏览器已支持无前缀的 gap。

  2. 响应式网格在窄屏下出现横向滚动条:minmax() 的最小值可能太大,或某个项目内容(如长单词、表格)太宽。检查 minmax(200px, 1fr) 的 200px 是否超过手机屏幕宽度;给项目内容加 overflow-wrap: break-word;或给网格项目加 min-width: 0。

  3. 想让某个项目跨越多行多列,但后面的项目位置乱了:这是自动放置算法的正常行为。如果项目有 span 或显式位置,后续项目会寻找下一个可用空位。如需精确控制,给所有关键项目都显式指定 grid-column 和 grid-row,或使用 grid-template-areas 统一定义。

面试常问

  • 「Grid 和 Flexbox 的主要区别?如何选择?」 Grid 是二维布局系统,同时控制行和列,适合整体页面骨架和卡片矩阵。Flexbox 是一维布局系统,沿单一方向排列,适合导航栏、按钮组、表单行等线性排列。选择标准:需要同时控制行和列时用 Grid;只需要沿一个方向排列时用 Flex。实际项目中两者常嵌套使用:Grid 定义页面骨架,Flex 定义组件内部。

  • 「fr 单位的含义是什么?」 fr 是 fraction(份数)的缩写,表示剩余空间的比例分配。grid-template-columns: 1fr 2fr 1fr 表示三列按 1:2:1 分配可用空间。fr 与 minmax() 结合可实现弹性响应式轨道,如 minmax(200px, 1fr) 表示轨道至少 200px,最多参与剩余空间均分。

  • 「如何实现一个响应式卡片网格,不写媒体查询?」 使用 grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))。auto-fit 根据容器宽度自动计算能放几列,minmax(280px, 1fr) 确保每列至少 280px、最多均分剩余空间。窗口变窄时列数自动减少,变宽时自动增加,完全无需媒体查询。

自测三问

  1. grid-template-columns: repeat(3, 1fr) 和 grid-template-columns: 1fr 1fr 1fr 有什么区别?repeat(auto-fill, minmax(200px, 1fr)) 又有什么不同?
  2. 在 grid-template-areas 中,. 代表什么?如果一个区域在 ASCII 图中占据多个单元格,这些单元格必须是什么形状?
  3. 你想实现一个页面布局:顶部 header 通栏,左侧 sidebar 固定 250px,右侧 main 自适应,底部 footer 通栏。请写出 grid-template-areas 和 grid-template-columns/rows 的声明。

小结一句话

CSS Grid 用「先画棋盘,再放棋子」的二维思维,让复杂页面布局从「计算和 hack」变成「声明和放置」;fr 单位、minmax() 和 auto-fit 的组合,更是让响应式网格无需一行媒体查询。

延伸

  • MDN:CSS Grid 基础概念
  • MDN:grid-template-areas
  • CSS-Tricks:A Complete Guide to Grid
  • 下一课:响应式设计与现代 CSS——媒体查询、容器查询与流体排版。
加载本节练习…
← 上一课Flexbox 布局下一课 →响应式设计