CSS 零基础教程

使用 grid-template-rows 和 grid-template-columns 定义行列

CSS Grid 是一个强大的布局工具,它能让你相对轻松地创建复杂的响应式设计。

与主要用于一维布局的 Flexbox 不同,Grid 擅长二维布局,能够同时控制行和列。

使用 CSS Grid 的基础在于定义网格本身的结构。这涉及到指定行和列的数量及尺寸,通过 grid-template-rowsgrid-template-columns 属性来实现。理解如何有效地使用这些属性,是挖掘 CSS Grid 全部潜力和创建精致布局的关键。

1. 理解 grid-template-rowsgrid-template-columns

这两个属性用于定义网格容器的行和列。它们指定了行和列的数量,以及每一行和每一列的大小。

  • grid-template-rows: 定义网格容器中每一行的高度。
  • grid-template-columns: 定义网格容器中每一列的宽度。

你可以使用各种单位、关键字和函数来为这些属性赋值,从而灵活地创建不同的网格布局。

2. 基本语法

grid-template-rowsgrid-template-columns 的基本语法涉及列出每一行或每一列的大小,中间用空格分隔。

.grid-container {
  display: grid;
  grid-template-rows: 100px 200px 150px; /* 定义三行,高度分别为 100px, 200px, 和 150px */
  grid-template-columns: 1fr 2fr 1fr; /* 定义三列,使用弹性宽度 */
}

在这个例子中,网格容器被定义为三行三列。grid-template-rows 属性以像素为单位指定了每行的高度,而 grid-template-columns 属性使用了 fr 单位,它代表网格容器中可用空间的一部分(fraction)。

3. 使用固定单位 (px, em, rem)

你可以使用像像素 (px)、em 和 rem 这样的固定单位来指定行和列的确切大小。

.grid-container {
  display: grid;
  grid-template-rows: 100px 150px 200px;
  grid-template-columns: 200px 150px 200px;
}

在这个例子中,行和列都有固定的大小。第一行高 100px,第二行 150px,第三行 200px。同样,列宽分别为 200px、150px 和 200px。

  • 适用场景: 假设你要创建一个展示产品图片的网格。你可以使用固定单位来确保每张图片都有其一致的尺寸和宽高比,而不管屏幕大小如何。
  • 反面教材: 仅仅使用固定单位可能导致不同屏幕尺寸上的布局问题。如果内容超出了固定尺寸,它可能会溢出,或者布局在小屏幕上无法很好地适应。

4. 使用弹性单位 (fr)

fr 单位代表网格容器中可用空间的一份。它是创建适应不同屏幕尺寸的响应式布局的强大工具。

.grid-container {
  display: grid;
  grid-template-rows: 1fr 2fr 1fr;
  grid-template-columns: 1fr 1fr 1fr;
}

在这个例子中,行和列使用 fr 单位来调整大小。

  • grid-template-rows 指定第二行的高度应该是第一行和第三行的两倍。
  • grid-template-columns 将可用宽度在三列之间平均分配。
  • 适用场景: 想象一下设计一个带有主要内容区域和两个侧边栏的仪表盘。你可以使用 fr 单位为主要内容区域分配更多空间,同时确保侧边栏保持比例大小。
  • 反面教材: 使用 fr 单位时,要考虑最小内容尺寸。如果网格项中的内容需要的空间超过了分配的比例,可能会导致布局破坏。

5. 使用百分比 (%)

百分比可用于相对于网格容器的大小来定义行和列的大小。

.grid-container {
  display: grid;
  grid-template-rows: 20% 60% 20%;
  grid-template-columns: 25% 50% 25%;
}

在这个例子中,行高分别是网格容器高度的 20%、60% 和 20%,而列宽分别是网格容器宽度的 25%、50% 和 25%。

  • 适用场景: 考虑一种场景,你希望创建一个占据其父容器全宽和全高的网格布局。你可以使用百分比来确保网格项随父容器成比例缩放。
  • 反面教材: 与其他单位相比,使用百分比可能不够精确,特别是在处理复杂布局时。行和列的实际大小可能会根据网格容器的大小和网格项内的内容而变化。

6. 使用 auto 关键字

auto 关键字允许网格根据其中的内容自动调整行或列的大小。

.grid-container {
  display: grid;
  grid-template-rows: auto 1fr auto;
  grid-template-columns: 1fr auto 1fr;
}

在这个例子中:

  • 第一行和第三行根据其内容自动调整大小,而第二行占据剩余的可用空间。
  • 同样,第二列根据其内容自动调整大小,而第一列和第三列平均分享剩余的可用空间。
  • 适用场景: 这对于包含页眉和页脚(由内容定义高度)以及填充剩余空间的主要内容区域的布局非常有用。
  • 反面教材: 过度依赖 auto 可能会导致不可预测的布局,特别是当内容大小变化很大时。通常最好将 auto 与其他单位结合使用以获得更多控制。

7. 使用 minmax() 函数

minmax() 函数定义了一个大小范围,大于等于 min 且小于等于 max。它允许你为行和列设置最小和最大尺寸。

.grid-container {
  display: grid;
  grid-template-rows: minmax(100px, auto) 1fr minmax(150px, auto);
  grid-template-columns: minmax(200px, 1fr) 2fr minmax(150px, 1fr);
}

在这个例子中:

  • 第一行的最小高度为 100px,并且可以增长以适应其内容 (auto)。
  • 第三行的最小高度为 150px,并且也可以增长以适应其内容。
  • 第一列的最小宽度为 200px,并且可以增长以填充可用空间的一份 (1fr)。
  • 适用场景: 这对于创建响应式布局非常有用,其中行或列应该有一个最小尺寸,但也可以增长以容纳更大的内容。
  • 反面教材: 如果最小尺寸太大,可能会导致内容溢出或布局在小屏幕上被破坏。

8. 使用 repeat() 函数

repeat() 函数简化了定义多个具有相同大小的行或列的过程。它接受两个参数:重复的次数和每一行或列的大小。

.grid-container {
  display: grid;
  grid-template-rows: repeat(3, 1fr); /* 等同于: 1fr 1fr 1fr */
  grid-template-columns: repeat(4, 25%); /* 等同于: 25% 25% 25% 25% */
}

在这个例子中:

  • grid-template-rows 定义了三行,每行高度为 1fr。
  • grid-template-columns 定义了四列,每列宽度为 25%。
  • 适用场景: 这对于创建具有大量相同大小的行或列的网格非常有用,例如图片画廊或数据表格。
  • 反面教材: 虽然 repeat() 很方便,但它可能不适用于行或列大小各不相同的布局。

9. 混合使用不同的单位和函数

你可以组合使用不同的单位和函数来创建复杂且灵活的网格布局。

.grid-container {
  display: grid;
  grid-template-rows: auto 1fr minmax(100px, auto);
  grid-template-columns: 200px 1fr repeat(2, 100px);
}

在这个例子中:

  • grid-template-rows 定义了三行不同的尺寸行为:第一行由内容自动决定,第二行占据剩余空间,第三行最小 100px 并可随内容增长。
  • grid-template-columns 定义了四列:第一列固定 200px,第二列占据可用空间,第三和第四列固定 100px。
  • 适用场景: 这允许对网格布局进行非常精细的控制,建议用于需要适应不同视口大小和内容的复杂布局。
  • 反面教材: 这也可能导致难以理解和维护的布局。在灵活性和简单性之间取得平衡很重要。

10. 实战案例与演示

让我们创建几个实际例子来演示 grid-template-rowsgrid-template-columns 的用法。

10.1 案例 1:基础网格布局

这个例子创建了一个包含三行三列的基础网格布局,行高使用固定单位,列宽使用弹性单位。

<!DOCTYPE html>
<html>
<head>
<style>
.grid-container {
  display: grid;
  grid-template-rows: 100px 150px 100px;
  grid-template-columns: 1fr 2fr 1fr;
  gap: 10px;
  background-color: #2196F3;
  padding: 10px;
}
.grid-container > div {
  background-color: rgba(255, 255, 255, 0.8);
  text-align: center;
  padding: 20px 0;
  font-size: 30px;
}
</style>
</head>
<body>
<h1>基础网格布局</h1>
<div class="grid-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
</div>
</body>
</html>

在此示例中,grid-template-rows 定义了三个高度分别为 100px、150px 和 100px 的行。grid-template-columns 定义了三列,其中第二列的宽度是第一列和第三列的两倍。gap 属性在网格项之间添加了 10px 的间距。

10.2 案例 2:响应式网格布局

这个例子创建了一个具有灵活列数的响应式网格布局,使用了 repeat() 函数和 minmax() 函数。

<!DOCTYPE html>
<html>
<head>
<style>
.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px;
  background-color: #2196F3;
  padding: 10px;
}
.grid-container > div {
  background-color: rgba(255, 255, 255, 0.8);
  text-align: center;
  padding: 20px 0;
  font-size: 30px;
}
</style>
</head>
<body>
<h1>响应式网格布局</h1>
<div class="grid-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
</div>
</body>
</html>

在此示例中,grid-template-columns 使用带有 auto-fit 关键字的 repeat() 函数,以创建尽可能多的列,每列最小宽度为 200px,最大宽度为 1fr。这确保了当网格项在同一行无法容纳时,会自动换行到下一行。

10.3 案例 3:复杂网格布局

这个例子创建了一个更复杂的网格布局,具有不同的行高和列宽,结合使用了固定单位、弹性单位和 auto 关键字。

<!DOCTYPE html>
<html>
<head>
<style>
.grid-container {
  display: grid;
  grid-template-rows: auto 1fr minmax(100px, auto);
  grid-template-columns: 200px 1fr repeat(2, 100px);
  gap: 10px;
  background-color: #2196F3;
  padding: 10px;
}
.grid-container > div {
  background-color: rgba(255, 255, 255, 0.8);
  text-align: center;
  padding: 20px 0;
  font-size: 30px;
}
</style>
</head>
<body>
<h1>复杂网格布局</h1>
<div class="grid-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
  <div>10</div>
  <div>11</div>
  <div>12</div>
</div>
</body>
</html>

在此示例中,grid-template-rowsgrid-template-columns 定义了混合尺寸行为,展示了如何精细控制网格的结构。