CSS 零基础教程

CSS Grid 容器与项目

1 Grid 容器 (The Grid Container)

1.1 创建一个 Grid 容器

要开始使用 CSS Grid,你首先需要定义一个 Grid 容器 (Grid Container)。这是包含所有网格项的父元素。

你可以通过将元素的 display 属性设置为 gridinline-grid 来创建网格容器。

  • display: grid;: 这会使元素成为块级网格容器,意味着它将占据其可用的全部宽度。
  • display: inline-grid;: 这会使元素成为行内级网格容器,意味着它只占据包含其内容所需的宽度。
.container {
  display: grid; /* 或者 inline-grid */
}

考虑我们虚构的公司 "StellarTech",它需要一个新的网站布局。假设他们有一个 <div class="wrapper"> 元素,将包含其主页的所有主要内容。要使此元素成为网格容器,你只需添加以下 CSS:

.wrapper {
  display: grid;
}

现在,.wrapper 元素的所有直接子元素都将变为 Grid 项目 (Grid Items)

1.2 显式网格 (Explicit) vs. 隐式网格 (Implicit)

当你创建一个网格容器时,你本质上是在为你的内容建立一个结构。这种结构可以通过两种方式定义:显式和隐式。

  • 显式网格 (Explicit Grid): 这是指你使用 grid-template-rowsgrid-template-columns 等属性明确定义网格的行和列。(我们将在这个模块的下一章中介绍这些内容。)
  • 隐式网格 (Implicit Grid): 如果你不显式定义行和列,网格会根据需要自动创建它们以容纳网格项。这就是所谓的隐式网格。这些隐式行和列的大小由它们包含的内容决定。

例如,如果你只有三个网格项并且没有定义任何行或列,网格将创建一个包含三列的一行来容纳这些项目。

假设 StellarTech 在 .wrapper 中只有三个 div 元素:

<div class="wrapper">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

只要在 .wrapper 上使用 display: grid,浏览器就会创建一个包含一行三列的隐式网格。这些项目将水平排列。

1.3 Grid 容器的角色

Grid 容器负责建立网格布局上下文。这意味着它控制其直接子元素(网格项)如何根据网格规则进行定位和调整大小。容器本身不直接显示内容,而是作为布局的框架。

Grid 容器还定义了影响整个网格的属性,例如网格项之间的间距(使用 grid-gap,我们将在稍后的课程中介绍)以及网格在容器内的对齐方式。

2. Grid 项目 (Grid Items)

2.1 什么是 Grid 项目?

Grid 项目 (Grid Items) 是 Grid 容器的直接子元素

每个网格项占据网格内的一个或多个网格单元。默认情况下,网格项会自动放入下一个可用的空网格单元中,逐行填充网格。

回到我们的 StellarTech 示例,.wrapper 内部的三个 div 元素都是 Grid 项目。

<div class="wrapper">
  <div>Item 1</div> 
  <div>Item 2</div> 
  <div>Item 3</div> 
</div>

2.2 Grid 项目的自动放置

默认情况下,Grid 算法会自动将项目放入可用的网格单元中。算法按照项目在 HTML 源代码中出现的顺序放置它们,从左到右填充每一行(在从左到右的语言中)。如果你不指定网格项应该放在哪里,Grid 将找到下一个可用的空单元格。

使用 StellarTech 的例子,如果我们向 .wrapper 添加第四个 div 元素:

<div class="wrapper">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
</div>

现在的隐式网格将有一行四列,每个项目占据一个单元格。

2.3 对 Grid 项目进行排序

你可能还记得我们在 Flexbox 讨论中提到过 order 属性,它也可以用于 Grid 项目。它允许你更改网格项显示的顺序,而不管它们在 HTML 源代码中的顺序如何。

order 属性接受整数值;值越小的项目显示得越早。

例如,假设 StellarTech 希望 "Item 3" 首先显示:

<div class="wrapper">
  <div>Item 1</div>
  <div>Item 2</div>
  <div style="order: -1;">Item 3</div>
  <div>Item 4</div>
</div>
.wrapper {
  display: grid;
}

在这种情况下,"Item 3" 将首先显示,因为它具有最低的 order 值 (-1)。未指定 order 的项目默认值为 0。具有相同 order 值的项目按其源顺序显示。

注意: 使用 order 仅改变元素的视觉顺序,而不改变它们在 DOM 中的语义顺序。这对于可访问性很重要:屏幕阅读器仍将按原始源顺序读取元素。

3. 嵌套 Grid 容器

你可以将 Grid 容器嵌套在 Grid 项目内。这允许你创建更复杂和灵活的布局。嵌套的 Grid 容器就像任何其他 Grid 容器一样,拥有自己的 Grid 项目和布局规则。

想象一下,StellarTech 想要在 "Item 2" 内部添加一个小型的图片库。他们可以通过使 "Item 2" 本身成为一个 Grid 容器来实现这一点:

<div class="wrapper">
  <div>Item 1</div>
  <div class="nested-grid">
    <img src="image1.jpg" alt="Image 1">
    <img src="image2.jpg" alt="Image 2">
  </div>
  <div>Item 3</div>
  <div>Item 4</div>
</div>
.wrapper {
  display: grid;
}
.nested-grid {
  display: grid; /* 创建一个嵌套的 Grid 容器 */
  grid-template-columns: 1fr 1fr; /* 在嵌套网格中定义两列 */
}

在这个例子中,.nested-grid.wrapper 的一个 Grid 项目,但它同时也是 img 元素的 Grid 容器。这允许你在 "Item 2" 内部为图像创建一个两列布局。