显式和隐式网格的区别

Avatar of Manuel Matuzovic
Manuel Matuzovic

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费信用额度!

网格布局 最终使我们能够在 CSS 中定义网格并将项目放置到网格单元格中。 这本身就很棒,但事实上我们不必指定每个轨道,并且我们不必手动放置每个项目,这使得新模块更加出色。 网格足够灵活,可以适应其项目。

所有这些都由所谓的显式和隐式网格处理。

本文中的所有代码示例都附带图像,以便显示网格线和轨道。 如果您想自己修改代码,建议您下载Firefox Nightly,因为它目前拥有最好的DevTools 来调试网格。

显式网格

我们可以使用属性grid-template-rowsgrid-template-columnsgrid-template-areas来定义形成网格的固定数量的行和轨道。 这个手动定义的网格称为显式网格

具有 4 个垂直轨道(列)和 2 个水平轨道(行)的显式网格。(查看示例
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 100px 100px;
  grid-gap: 20px;
}

重复轨道

当我们定义grid-template-columns: 1fr 1fr 1fr 1fr;时,我们将获得四个垂直轨道,每个轨道的宽度为1fr。 我们可以使用repeat()表示法来自动执行此操作,例如grid-template-columns: repeat(4, 1fr);。 第一个参数指定重复次数,第二个参数指定轨道列表,该列表将重复该次数。

轨道列表? 是的,您实际上可以重复多个轨道。

轨道的自动重复

由 repeat 表示法生成的,具有 4 个每个宽度为 100px 的垂直轨道的显式网格。(查看示例

repeat 表示法非常有用,但它可以进一步自动化。 我们可以使用auto-fillauto-fit关键字,而不是设置固定的重复次数。

自动填充轨道

auto-fill关键字创建尽可能多的轨道以适合网格容器,而不会导致网格溢出。

重复尽可能多的宽度为 100px 的垂直轨道,以适合网格容器。(查看示例
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
  grid-gap: 20px;
}

请注意,repeat(auto-fill, 1fr);将只创建一个轨道,因为宽度为1fr的单个轨道已经填满了整个网格容器是一个无效的声明(也许它改变了?我不知道)。

自动调整轨道

auto-fit关键字的行为与auto-fill相同,除了在网格项目放置之后,它只会创建必要的轨道,并且任何空的重复轨道都会折叠。

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, 100px);
  grid-gap: 20px;
}

在本节中使用的示例中,网格在使用repeat(auto-fit, 100px);repeat(4, 100px);时外观相同。 当有超过 4 个网格项目时,差异可见。

如果有更多项目,auto-fit会创建更多列。

使用 auto-fit 关键字的 repeat 表示法创建必要的轨道,以及适合网格容器的轨道。(查看示例

另一方面,如果在 repeat 表示法中使用固定数量的垂直轨道,并且项目的数量超过此值,则会添加更多行。 您可以在下一节中阅读更多相关内容:隐式网格

如果项目数超过垂直轨道数,则会添加更多行。(查看示例

出于方便起见,我在以上示例中使用了grid-template-columns,但所有规则也适用于grid-template-rows

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
  grid-template-rows: repeat(auto-fill, 100px);
  grid-gap: 20px;
  height: 100%;
}

html, body {
  height: 100%;
}
在两个轴上使用 auto-fill 关键字的 repeat 表示法。(查看示例

隐式网格

如果网格项目多于网格中的单元格,或者当网格项目放置在显式网格之外时,网格容器会通过向网格添加网格线来自动生成网格轨道。 显式网格连同这些额外的隐式轨道和线一起形成了所谓的隐式网格

放置在显式网格之外的两个项目导致创建隐式线和轨道(查看示例
.item:first-child {
  grid-column-start: -1;
}

.item:nth-child(2) {
  grid-row-start: 4;
}

隐式轨道的宽度和高度会自动设置。 它们仅大到足以容纳放置的网格项目,但可以更改此默认行为。

隐式轨道的尺寸

grid-auto-rowsgrid-auto-columns属性使我们可以控制隐式轨道的尺寸。

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: 100px 100px;
  grid-gap: 20px;
  grid-auto-columns: 200px;
  grid-auto-rows: 60px;
}

无论网格项目是否适合,隐式轨道现在始终宽度为200px,高度为60px

隐式轨道的固定宽度和高度(在 CodePen 中查看

您可以通过使用minmax()表示法指定范围来使尺寸隐式轨道更灵活。

.grid {
  grid-auto-columns: minmax(200px, auto);
  grid-auto-rows: minmax(60px, auto);
}

隐式轨道的宽度至少为 200px,高度至少为 60px,但如果内容需要,它们会扩展。

将网格扩展到开头

隐式轨道可能不仅仅添加到显式网格的末尾。 显式网格也可能需要扩展到开头。

一个向开头扩展了一行一列的隐式网格(查看示例
.item:first-child {
  grid-row-end: 2;
  grid-row-start: span 2;
}

.item:nth-child(2) {
  grid-column-end: 2;
  grid-column-start: span 2;
}

每个项目都结束在第二行并跨越 2 个单元格(一个垂直,另一个水平)。 由于第二行之前只有一个单元格,因此在每一侧的网格开头都会添加另一个隐式轨道。

自动放置

如前所述,如果项目的数量超过单元格的数量,也会添加隐式轨道。 默认情况下,自动放置算法通过连续填充每一行来放置项目,并在必要时添加新行。 我们可以使用grid-auto-flow属性来指定自动放置的项目如何流入网格。

如果项目的数量超过单元格的数量,则会添加新列而不是行(在 CodePen 中查看
.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: 100px 100px;
  grid-gap: 20px;
  grid-auto-flow: column;
}

项目填充列,并创建额外的隐式列,而不是行。

不定义显式网格

由于可以使用grid-auto-rowsgrid-auto-columns来自动调整单元格大小,因此不必定义显式网格。

没有显式线和轨道的隐式网格(在 CodePen 中查看

.grid {
  display: grid;
  grid-auto-columns: minmax(60px, 200px);
  grid-auto-rows: 60px;
  grid-gap: 20px;
}

.item:first-child {
  grid-row: span 2;
}

.item:nth-child(2) {
  grid-column: 1 / span 2;
}

.item:nth-child(5) {
  grid-column: 3;
}

仅仅依靠隐式网格在与显式放置结合使用时可能会变得混乱且难以理解。在这个例子中,第一个项目被放置为auto并跨越 2 行,第二个项目被显式放置在第一列并跨越 2 列,从而创建了第二个垂直轨道。第三和第四个项目实际上都将自动放置在第四行,但第五个项目被显式放置在之前不存在的第三列中。这创建了第三个垂直轨道,并且由于网格的自动放置,第三个项目向上移动一行以填充空间。

结论

本文没有涵盖关于显式和隐式网格的所有知识,但它应该能让你对这个概念有一个深入的了解。了解为什么以及如何创建隐式线和轨道对于使用网格布局至关重要。

你可以在 CodePen 上的一个合集中找到本文中使用的所有示例

如果你想了解更多关于网格的信息,请查看网格完整指南CSS 网格入门网格示例CSS 网格布局的一些有趣事实