Skip to content

第七章:CSS Grid——掌握二维布局的终极武器

如果说 Flexbox 是一维布局的专家,那么 CSS Grid(网格布局) 就是二维布局的统治者

它允许你同时控制行(rows)和列(columns),精确地将页面划分为多个区域,实现以往需要复杂定位或 JavaScript 才能完成的复杂布局。

本章将深入 Grid 的四大核心概念:行、列、网格线、区域,并结合常见问题与实战案例,带你构建一个现代响应式图片画廊。


1. Grid 的核心概念

① 行(Rows)与 列(Columns)

通过 grid-template-rowsgrid-template-columns 定义网格的结构。

css
.container {
  display: grid;
  /* 定义 3 列:固定 200px + 自适应 1fr + 2fr */
  grid-template-columns: 200px 1fr 2fr;
  /* 定义 2 行:固定 100px + 自动高度 */
  grid-template-rows: 100px auto;
}
  • fr:自由空间分数(如 1fr 占 1 份,2fr 占 2 份)
  • minmax(min, max):定义尺寸范围,如 minmax(100px, 1fr)
  • repeat():简化重复定义,如 repeat(3, 1fr)
② 网格线(Grid Lines)

网格线是划分网格的参考线,从 1 开始编号。

css
.item {
  /* 从第 2 条列线开始,到第 4 条结束 */
  grid-column: 2 / 4;
  /* 从第 1 条行线开始,到第 3 条结束 */
  grid-row: 1 / 3;
}

也可使用负数从末尾计数:grid-column: -2 / -1

③ 网格区域(Grid Areas)

最直观的布局方式:用命名区域拼图。

css
.container {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  grid-template-columns: 200px 1fr;
  grid-template-rows: 80px 1fr 60px;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

优势:布局意图一目了然,修改只需调整字符串。


2. Grid vs Flexbox:何时使用?

场景推荐工具原因
一维布局(水平/垂直排列)✅ Flexbox更简单,行为更可预测
二维布局(行 + 列)✅ CSS Grid原生支持,无需嵌套
内容流式排列(如导航、按钮组)✅ Flexbox自动换行(flex-wrap)更自然
精确对齐(元素跨行跨列)✅ CSS Gridgrid-column, grid-row 精确控制
杂志式布局(不规则卡片)✅ CSS Gridgrid-template-areasgrid-auto-flow: dense
全屏应用布局✅ CSS Grid易于划分 header/sidebar/main/footer

🚫 反模式:用多层嵌套 Flexbox 实现二维布局 → 代码复杂,难以维护。


3. 常见问题与解决方案

问题 1:如何实现栅格布局中的对齐方式?
属性作用常用值
justify-items控制项目在中的水平对齐start, end, center, stretch
align-items控制项目在中的垂直对齐start, end, center, stretch
justify-content控制网格整体在容器中的水平对齐start, center, space-between
align-content控制网格整体在容器中的垂直对齐start, center, space-around
css
.container {
  justify-items: center; /* 所有项目水平居中 */
  align-items: center;   /* 所有项目垂直居中 */
}

.special {
  justify-self: start; /* 覆盖,左对齐 */
  align-self: end;     /* 覆盖,底对齐 */
}
问题 2:如何定义网格间距?——gap 属性
css
.container {
  gap: 1rem;           /* 行与列间距 */
  row-gap: 20px;       /* 仅行间距 */
  column-gap: 10px;    /* 仅列间距 */
}

优势gap 不影响容器边界,无需计算 margin

问题 3:Grid 在嵌套布局中的应用

Grid 支持嵌套,即一个 Grid 项本身也可以是另一个 Grid 容器。

css
.dashboard {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}

.card-1 { grid-column: span 8; }
.card-2 { grid-column: span 4; }

/* 嵌套 Grid:卡片内部布局 */
.card-1 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
  gap: 0.5rem;
}

优势:内层布局独立,不影响外层,适合模块化设计。


4. 实战案例:构建一个响应式的图片画廊

HTML 结构
html
<div class="image-gallery">
  <figure class="gallery-item">
    <img src="photo1.jpg" alt="城市夜景" loading="lazy">
    <figcaption>城市夜景</figcaption>
  </figure>
  <!-- 更多图片... -->
</div>
CSS 样式
css
.image-gallery {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr; /* 移动端:单列 */
}

/* 平板:双列 */
@media (min-width: 600px) {
  .image-gallery {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* 桌面:自动填充列 */
@media (min-width: 1024px) {
  .image-gallery {
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  }
}

.gallery-item {
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}

.gallery-item img {
  width: 100%;
  height: 300px;
  object-fit: cover; /* 保持比例,裁剪填充 */
  transition: transform 0.3s ease;
}

.gallery-item:hover img {
  transform: scale(1.05); /* 悬停放大 */
}

结语:Grid 是现代布局的未来

CSS Grid 解放了前端开发者,让我们能像设计师一样思考布局。
它不是要取代 Flexbox,而是与之互补:

  • Flexbox:处理组件内部的一维排列
  • Grid:处理页面整体的二维结构

当你面对一个包含多个区块、需要精确对齐与响应式的复杂界面时,CSS Grid 往往是最优雅、最可维护的选择

下一章,我们将进入“响应式设计进阶:容器查询(Container Queries)与视口单位”。