Skip to content

Grid 容器属性:掌控网格布局的核心

想象你是一个城市规划师,需要设计一个新城区的街道布局。你需要决定有多少条大街(列),有多少条小巷(行),街道有多宽,建筑之间的间距有多大,以及建筑在地块中如何对齐。Grid 容器属性就像是你手中的规划工具,让你可以精确控制整个网格的结构和布局规则。

在上一章中,我们了解了 Grid 布局的基本概念。现在,让我们深入学习 Grid 容器的各种属性,它们是控制整个网格布局的核心。

定义网格结构

首先,我们需要定义网格的基本结构——有多少列、有多少行、每列多宽、每行多高。

grid-template-columns:定义列结构

grid-template-columns 属性定义网格有多少列,以及每列的宽度。这是 Grid 布局中最重要的属性之一。

固定宽度列

最简单的方式是使用固定宽度:

css
.grid {
  display: grid;
  grid-template-columns: 200px 300px 400px; /* 三列,宽度分别是 200px、300px、400px */
}

如果容器宽度是 900px,这三列刚好填满。如果容器更宽,右边会留下空白;如果容器更窄,网格会溢出。

弹性 fr 单位

fr 单位让网格变得弹性,它表示"可用空间的一份":

css
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr; /* 三列平分空间 */
}

假设容器宽度是 900px:

  • 总共 3 份(1 + 1 + 1)
  • 每份 = 900px ÷ 3 = 300px
  • 三列都是 300px

你可以使用不同的 fr 值创建不同的比例:

css
.grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr; /* 第一列是其他列的两倍 */
}

假设容器宽度是 900px:

  • 总共 4 份(2 + 1 + 1)
  • 每份 = 900px ÷ 4 = 225px
  • 第一列:225px × 2 = 450px
  • 第二列:225px
  • 第三列:225px

混合使用不同单位

Grid 的强大之处在于可以混合使用不同单位:

css
.grid {
  display: grid;
  grid-template-columns: 200px 1fr 2fr 150px;
  /* 固定 + 弹性 + 弹性 + 固定 */
}

假设容器宽度是 900px:

  1. 先分配固定宽度:200px + 150px = 350px
  2. 剩余空间:900px - 350px = 550px
  3. 弹性空间总份数:1 + 2 = 3 份
  4. 每份:550px ÷ 3 ≈ 183.3px
  5. 最终分配:
    • 第一列:200px(固定)
    • 第二列:183.3px(1 份)
    • 第三列:366.7px(2 份)
    • 第四列:150px(固定)

这种混合方式非常适合创建"侧边栏 + 弹性内容 + 侧边栏"的布局。

minmax() 函数

minmax() 函数定义列的最小和最大值:

css
.grid {
  display: grid;
  grid-template-columns: minmax(200px, 300px) 1fr 1fr;
  /* 第一列:最小 200px,最大 300px */
}

这很有用,因为你可以确保列不会太窄(小于 200px)也不会太宽(大于 300px)。

实际效果:

  • 如果容器很宽,第一列会达到 300px,然后停止增长,剩余空间被其他列平分
  • 如果容器很窄,第一列会保持 200px 的最小宽度

常见的用法是设置最小值,最大值用 fr

css
.grid {
  display: grid;
  grid-template-columns: minmax(200px, 1fr) minmax(200px, 1fr) minmax(200px, 1fr);
  /* 每列最小 200px,然后平分空间 */
}

这确保每列至少有 200px,但在宽屏幕上会平均分配额外的空间。

auto 关键字

auto 关键字让列根据内容自动调整大小:

css
.grid {
  display: grid;
  grid-template-columns: auto 1fr auto;
  /* 第一列和第三列根据内容调整,第二列占据剩余空间 */
}

这在创建导航栏时特别有用:

html
<nav class="navbar">
  <div class="logo">TechCorp</div>
  <div class="spacer"></div>
  <div class="nav-links">Home Products About Contact</div>
</nav>
css
.navbar {
  display: grid;
  grid-template-columns: auto 1fr auto;
  /* logo 和 nav-links 根据内容大小,中间的 spacer 填充剩余空间 */
  align-items: center;
  background-color: #333;
  padding: 15px 30px;
}

.logo {
  color: white;
  font-size: 24px;
  font-weight: bold;
}

.nav-links {
  color: white;
}

repeat() 函数

当有很多相同的列时,repeat() 函数让代码更简洁:

css
/* 传统写法 */
.grid {
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
}

/* 使用 repeat() */
.grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  /* 重复 6 次 1fr */
}

repeat() 可以重复一个模式:

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 100px 200px);
  /* 创建 6 列:100px 200px 100px 200px 100px 200px */
}

auto-fill 和 auto-fit

这两个关键字配合 repeat() 使用,可以创建响应式的列:

css
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, 200px);
  /* 自动填充尽可能多的 200px 宽的列 */
}

假设容器宽度是 850px:

  • 能放下 4 列(4 × 200px = 800px)
  • 剩余 50px 留白

auto-fitauto-fill 类似,但会收缩空列:

css
.grid-fill {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  /* auto-fill:会保留空列 */
}

.grid-fit {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  /* auto-fit:会收缩空列,让存在的列占据更多空间 */
}

实际应用:

css
.card-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

这会创建一个完全响应式的卡片布局:

  • 每张卡片最小 250px
  • 容器宽度够大时,卡片会平分空间
  • 容器变窄时,会自动减少列数
  • 完全不需要媒体查询!

grid-template-rows:定义行结构

grid-template-rows 的用法与 grid-template-columns 完全相同,只是它定义的是行而不是列。

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px 200px 150px; /* 三行,高度分别是 100px、200px、150px */
}

隐式网格和 grid-auto-ros

Grid 有一个聪明的特性:如果项目数量超过了你定义的网格单元,Grid 会自动创建新行。这些新行被称为"隐式网格行"。

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 3 列 */
  grid-template-rows: 150px; /* 只定义第一行 150px */
  grid-auto-rows: 100px; /* 隐式行的高度是 100px */
}

如果有 10 个项目:

  • 前 3 个在第一行(高度 150px)
  • 第 4-6 个在第二行(高度 100px,隐式行)
  • 第 7-9 个在第三行(高度 100px,隐式行)
  • 第 10 个在第四行(高度 100px,隐式行)

使用 auto 让行高度根据内容自动调整:

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: auto; /* 行高度根据内容自动调整 */
}

或者使用 minmax() 设置最小和最大高度:

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
  /* 每行最小 100px,最大根据内容 */
}

这确保每行至少有 100px 高,但如果内容更多,行会自动扩展。

间距控制

gap:项目之间的间距

gap 属性(以前叫 grid-gap)控制网格项目之间的间距。它是一个简写属性。

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px; /* 行间距和列间距都是 20px */
}

你也可以分别设置行间距和列间距:

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px 30px; /* 行间距 20px,列间距 30px */
  /* 或者使用单独的属性: */
  /* row-gap: 20px; */
  /* column-gap: 30px; */
}

重要提示: gap 只在项目之间创建间距,不会在容器边缘创建间距。如果你需要容器边缘也有间距,使用 padding

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px; /* 项目之间 20px */
  padding: 20px; /* 容器边缘也有 20px */
}

对齐控制

Grid 提供了强大的对齐控制,可以精确控制项目在单元格中的位置。

justify-items:水平方向对齐

justify-items 控制所有网格项目在其单元格中的水平对齐方式。

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 200px);
  justify-items: start; /* 默认值:项目靠左对齐 */
}

可能的值:

  • start:靠左对齐(默认)
  • end:靠右对齐
  • center:水平居中
  • stretch:拉伸填充整个单元格的宽度
css
/* 示例:居中对齐 */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 200px);
  justify-items: center; /* 所有项目在单元格中水平居中 */
}

.item {
  width: 100px; /* 项目宽度小于单元格宽度 200px */
  background-color: #2196f3;
}
/* 每个项目都会在其 200px 的单元格中居中显示 */
css
/* 示例:拉伸 */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 200px);
  justify-items: stretch; /* 项目拉伸填充单元格 */
}

.item {
  /* 不要设置 width,否则 stretch 不生效 */
  background-color: #2196f3;
}
/* 每个项目都会拉伸到 200px 宽 */

align-items:垂直方向对齐

align-items 控制所有网格项目在其单元格中的垂直对齐方式。

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 150px; /* 每行 150px */
  align-items: start; /* 项目靠上对齐 */
}

可能的值:

  • start:靠上对齐
  • end:靠下对齐
  • center:垂直居中
  • stretch:拉伸填充整个单元格的高度(默认)
css
/* 实用示例:完美居中 */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 150px;
  justify-items: center; /* 水平居中 */
  align-items: center; /* 垂直居中 */
  gap: 20px;
}

/* 所有项目都会在其单元格中完美居中 */

place-items:对齐方式简写

place-itemsalign-itemsjustify-items 的简写:

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  place-items: center center;
  /* 相当于: */
  /* align-items: center; */
  /* justify-items: center; */
}

如果只写一个值,两个方向都使用这个值:

css
.grid {
  place-items: center;
  /* 相当于: */
  /* align-items: center; */
  /* justify-items: center; */
}

justify-content:整个网格的水平对齐

前面的 justify-items 控制项目在单元格中的对齐。justify-content 则控制整个网格在容器中的水平对齐。

这在网格总宽度小于容器宽度时非常有用:

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 200px); /* 总宽度 600px */
  width: 900px; /* 容器宽度 900px */
  justify-content: start; /* 默认:网格靠左 */
}

可能的值:

  • start:靠左对齐(默认)
  • end:靠右对齐
  • center:居中
  • stretch:列拉伸以填充容器
  • space-between:第一列靠左,最后一列靠右,中间列平分剩余空间
  • space-around:每列两侧有相等的空间
  • space-evenly:所有间距相等
css
/* 示例:space-between */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 200px);
  width: 900px;
  justify-content: space-between;
  background-color: #f5f5f5;
  padding: 20px;
}
/* 第一列贴左边,最后一列贴右边,中间有 150px 空隙 */

align-content:整个网格的垂直对齐

align-content 控制整个网格在容器中的垂直对齐,当网格总高度小于容器高度时使用。

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 100px); /* 总高度 200px */
  height: 500px; /* 容器高度 500px */
  align-content: center; /* 网格垂直居中 */
}

可能的值与 justify-content 相同:startendcenterstretchspace-betweenspace-aroundspace-evenly

place-content:content 对齐简写

place-contentalign-contentjustify-content 的简写:

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 150px);
  grid-template-rows: repeat(2, 100px);
  width: 600px;
  height: 400px;
  place-content: center center;
  /* 整个网格在容器中水平和垂直都居中 */
}

grid-auto-flow:控制自动放置

grid-auto-flow 控制项目的自动放置方向。

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-flow: row; /* 默认值:按行填充 */
}

可能的值:

  • row(默认):按行填充,从左到右,然后下一行
  • column:按列填充,从上到下,然后下一列
  • dense:尝试填充网格中的空洞
css
/* 按列填充 */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
  grid-auto-flow: column;
}
/* 项目会按列填充:
   1 4 7
   2 5 8
   3 6 9
*/

dense 关键字会尝试填充网格中的空洞:

css
.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-flow: dense;
}

.item-wide {
  grid-column: span 2; /* 占据 2 列 */
}

如果某个宽项目放不下当前行的剩余空间,dense 会让后面的小项目先填充空位,而不是留下空白。

实际应用示例

让我们把这些属性组合起来,创建一些实用的布局。

响应式作品集

html
<div class="portfolio">
  <div class="project project-featured">Featured Project</div>
  <div class="project">Project 2</div>
  <div class="project">Project 3</div>
  <div class="project">Project 4</div>
  <div class="project">Project 5</div>
  <div class="project">Project 6</div>
</div>
css
.portfolio {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  /* 响应式列:最小 300px,自动调整列数 */
  grid-auto-rows: 250px;
  /* 每行 250px */
  gap: 20px;
  padding: 20px;
}

.project {
  background-color: #e3f2fd;
  border-radius: 8px;
  padding: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  transition: transform 0.3s;
}

.project:hover {
  transform: scale(1.05);
}

.project-featured {
  grid-column: span 2; /* 占据 2 列 */
  grid-row: span 2; /* 占据 2 行 */
  background-color: #2196f3;
  color: white;
  font-size: 24px;
}

这个布局会:

  • 在宽屏幕上显示多列
  • 在窄屏幕上自动减少列数
  • 特色项目占据 2×2 的空间
  • 完全响应式,无需媒体查询

仪表板布局

css
.dashboard {
  display: grid;
  grid-template-columns: repeat(12, 1fr); /* 12 列系统 */
  grid-auto-rows: minmax(100px, auto);
  gap: 20px;
  padding: 20px;
}

.header {
  grid-column: 1 / 13; /* 占据所有 12 列 */
  background-color: #333;
  color: white;
  padding: 20px;
}

.sidebar {
  grid-column: 1 / 3; /* 占据 2 列 */
  grid-row: 2 / 5; /* 占据 3 行 */
  background-color: #f5f5f5;
  padding: 20px;
}

.main-widget {
  grid-column: 3 / 9; /* 占据 6 列 */
  grid-row: 2 / 4; /* 占据 2 行 */
  background-color: #2196f3;
  color: white;
  padding: 30px;
}

.stats {
  grid-column: 9 / 13; /* 占据 4 列 */
  background-color: #e3f2fd;
  padding: 20px;
}

.chart {
  grid-column: 3 / 9;
  background-color: white;
  border: 1px solid #ddd;
  padding: 20px;
}

.recent {
  grid-column: 9 / 13;
  grid-row: 3 / 5;
  background-color: white;
  border: 1px solid #ddd;
  padding: 20px;
}

总结

Grid 容器属性给了你完全的布局控制权。让我们回顾一下核心属性:

定义结构:

  • grid-template-columns:定义列结构
  • grid-template-rows:定义行结构
  • grid-auto-rows:定义隐式行的大小
  • grid-auto-flow:控制自动放置方向

间距控制:

  • gap:项目之间的间距(简写)
  • row-gap:行间距
  • column-gap:列间距

项目对齐:

  • justify-items:项目在单元格中的水平对齐
  • align-items:项目在单元格中的垂直对齐
  • place-items:对齐简写

网格对齐:

  • justify-content:整个网格在容器中的水平对齐
  • align-content:整个网格在容器中的垂直对齐
  • place-content:对齐简写

关键技巧:

  • 使用 fr 单位创建弹性列
  • 使用 minmax() 设置尺寸范围
  • 使用 repeat() 简化重复模式
  • 使用 auto-fitauto-fill 创建响应式布局
  • 混合使用固定和弹性单位获得最大灵活性

掌握这些容器属性,你就能创建任何你想要的网格布局。在下一节中,我们将学习 Grid 项目属性,它们让你可以精确控制单个项目在网格中的位置和大小。