使用基于线的定位的网格布局
在网格布局的基本概念指南中,我们简要了解了如何使用行号在网格上定位项目。在本指南中,我们将全面探讨此规范的基本功能如何工作。
从编号的行开始探索网格是最合乎逻辑的起点,因为当您使用网格布局时,您始终拥有编号的行。行按列和行编号,并从1开始索引。请注意,网格是根据文档的书写模式进行索引的。在从左到右的语言中,例如英语,第 1 行位于网格的左侧。如果您正在使用从右到左的语言,例如阿拉伯语,则第 1 行将位于网格的右侧。我们将在网格、逻辑值和书写模式指南中了解更多关于书写模式与网格之间交互的信息。
一个基本示例
作为一个基本示例,我们创建一个具有 3 列轨道和 3 行轨道的网格。这使我们在每个维度上都有 4 条线。
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 100px);
}
在我们的网格容器中,我们包含四个子元素。
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
如果我们不以任何方式将它们放置在网格上,它们将根据自动放置规则进行布局,每个项目占据前四个单元格中的一个。您可以使用浏览器开发工具检查网格,以查看网格如何定义列和行。

通过行号定位项目
我们可以使用基于线的放置来控制这些项目在网格上的位置。我们可以使用 grid-column-start 和 grid-column-end 属性使第一个项目从网格的最左侧开始并跨越一个列轨道。使用 grid-row-start 和 grid-row-end,我们使项目从网格顶部的第一行线开始,并跨越到第四行线。
.box1 {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 4;
}
当您放置一些项目时,网格上的其他项目将继续使用自动放置规则进行布局。此行为在网格布局中的自动放置指南中解释。现在,请观察网格如何将未放置的项目布局到网格的空单元格中。
使用相同的属性但使用不同的值单独处理每个项目,我们放置所有四个项目,跨越行和列轨道。
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
.box1 {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 4;
}
.box2 {
grid-column-start: 3;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
}
.box3 {
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 2;
}
.box4 {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 3;
grid-row-end: 4;
}
请注意,如果需要,我们可以将单元格留空。网格布局的优点之一是能够在我们的设计中拥有空白而无需任何技巧。
grid-column 和 grid-row 简写
上一个示例为了定位每个项目,代码量相当大。毫无疑问,您应该知道存在一种简写。grid-column-start 和 grid-column-end 属性可以合并为 grid-column,grid-row-start 和 grid-row-end 可以合并为 grid-row。在此示例中,我们使用这些简写属性复制了上面的示例
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
.box1 {
grid-column: 1 / 2;
grid-row: 1 / 4;
}
.box2 {
grid-column: 3 / 4;
grid-row: 1 / 3;
}
.box3 {
grid-column: 2 / 3;
grid-row: 1 / 2;
}
.box4 {
grid-column: 2 / 4;
grid-row: 3 / 4;
}
默认跨度
在上面的示例中,为了演示这些属性,我们指定了每一行的起始线和结束线,但是实际上,如果一个项目只跨越一个轨道,您可以省略 grid-column-end 或 grid-row-end 值。Grid 默认跨越一个轨道。
使用长格式放置的默认跨度
这意味着我们最初的长格式示例将如下所示
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
.box1 {
grid-column-start: 1;
grid-row-start: 1;
grid-row-end: 4;
}
.box2 {
grid-column-start: 3;
grid-row-start: 1;
grid-row-end: 3;
}
.box3 {
grid-column-start: 2;
grid-row-start: 1;
}
.box4 {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 3;
}
使用简写放置的默认跨度
我们的简写代码如下所示,对于仅跨越一个轨道的项目,没有正斜杠和第二个值。
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
.box1 {
grid-column: 1;
grid-row: 1 / 4;
}
.box2 {
grid-column: 3;
grid-row: 1 / 3;
}
.box3 {
grid-column: 2;
grid-row: 1;
}
.box4 {
grid-column: 2 / 4;
grid-row: 3;
}
grid-area 属性
我们可以更进一步,用一个属性定义每个区域——grid-area。grid-area 的值顺序如下。
– grid-row-start – grid-column-start – grid-row-end – grid-column-end
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
.box1 {
grid-area: 1 / 1 / 4 / 2;
}
.box2 {
grid-area: 1 / 3 / 3 / 4;
}
.box3 {
grid-area: 1 / 2 / 2 / 3;
}
.box4 {
grid-area: 3 / 2 / 4 / 4;
}
grid-area 的值顺序可能看起来有点奇怪——例如,它与我们指定 margin 和 padding 的简写方向相反。这可能是因为 CSS 网格布局使用 CSS 书写模式中定义的流相对方向。我们将在网格、逻辑值和书写模式中探讨网格如何与书写模式一起工作。目前,请考虑四个流相对方向的概念
block-startblock-endinline-startinline-end
我们使用的是英语,一种从左到右的语言。我们的 block-start 是网格容器的顶行线,block-end 是容器的最后一行线。我们的 inline-start 是左列线,因为 inline-start 始终是当前书写模式下文本开始写入的点,而 inline-end 是我们网格的最后一列线。
当我们使用 grid-area 属性指定网格区域时,我们首先定义起始行 block-start 和 inline-start,然后定义结束行 block-end 和 inline-end。这最初看起来很奇怪,因为我们习惯了 top、right、bottom 和 left 的物理属性,但如果您开始将网站视为在不同书写模式下多方向的,它会更有意义。
倒数
我们还可以从网格的块和内联末端向后计数,对于英语,这将是右侧列线和最后一行线。显式网格的最后一行可以表示为 -1,您可以从那里倒数——所以倒数第二行是 -2。
请注意,负值仅与显式网格相关。最后一行是由 grid-template-columns 和 grid-template-rows 定义的网格的最后一行,并且不考虑在 _隐式网格_ 中添加的任何行或列。
在下一个示例中,我们通过从网格的右侧和底部放置项目来翻转我们正在使用的布局。
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
.box1 {
grid-column-start: -1;
grid-column-end: -2;
grid-row-start: -1;
grid-row-end: -4;
}
.box2 {
grid-column-start: -3;
grid-column-end: -4;
grid-row-start: -1;
grid-row-end: -3;
}
.box3 {
grid-column-start: -2;
grid-column-end: -3;
grid-row-start: -1;
grid-row-end: -2;
}
.box4 {
grid-column-start: -2;
grid-column-end: -4;
grid-row-start: -3;
grid-row-end: -4;
}
跨网格拉伸项目
能够寻址网格的起始线和结束线很有用,因为您可以这样将项目一直拉伸到网格
.item {
grid-column: 1 / -1;
}
间隙或小巷
CSS 网格包括通过 column-gap 和 row-gap 属性或 gap 简写在列和行轨道之间添加间隙的功能。
间隙只出现在网格轨道之间,它们不会在容器的顶部和底部、左侧或右侧添加空间。我们可以通过在网格容器上使用这些属性来为我们之前的示例添加间隙。
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
.box1 {
grid-column: 1;
grid-row: 1 / 4;
}
.box2 {
grid-column: 3;
grid-row: 1 / 3;
}
.box3 {
grid-column: 2;
grid-row: 1;
}
.box4 {
grid-column: 2 / 4;
grid-row: 3;
}
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 100px);
column-gap: 20px;
row-gap: 1em;
}
间隙简写
这两个属性也可以用简写形式 gap 表示。如果您只为 gap 提供一个值,它将同时应用于列间隙和行间隙。如果您指定两个值,则第一个值用于 row-gap,第二个值用于 column-gap。
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 100px);
gap: 1em 20px;
}
就项目的基于线的定位而言,间隙的作用就像该线获得了额外的宽度。任何从该线开始的事物都在间隙之后开始,并且您无法寻址间隙或将任何东西放置到其中。如果您想要更像常规轨道那样的间隙,您可以为此目的定义一个轨道。
使用 span 关键字
除了通过数字指定起始线和结束线外,您还可以指定起始线,然后使用 span 关键字指定您希望区域跨越的轨道数量。
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
.box1 {
grid-column: 1;
grid-row: 1 / span 3;
}
.box2 {
grid-column: 3;
grid-row: 1 / span 2;
}
.box3 {
grid-column: 2;
grid-row: 1;
}
.box4 {
grid-column: 2 / span 2;
grid-row: 3;
}
您还可以在 grid-row-start/grid-row-end 和 grid-column-start/grid-column-end 的值中使用 span 关键字。以下两个示例将创建相同的网格区域。在第一个示例中,我们设置了起始行线,然后指定了我们希望区域覆盖 3 条轨道。该区域将从第 1 行开始,并在从第 1 行算起的 3 条线处结束;也就是说,该区域将在第 4 行结束。
.box1 {
grid-column-start: 1;
grid-row-start: 1;
grid-row-end: span 3;
}
在第二个示例中,我们指定了我们希望项目结束的结束行线,然后将起始线设置为 span 3。这意味着项目将需要从指定的行线向上跨越。该区域将从第 4 行开始,并跨越 3 行到第 1 行。
.box1 {
grid-column-start: 1;
grid-row-start: span 3;
grid-row-end: 4;
}
为了熟悉网格中基于线的定位,请尝试通过将项目放置到具有不同列数的网格上来构建一些常见布局。请记住,如果您不放置所有项目,任何剩余的项目将根据自动放置规则进行放置。这可能会产生您想要的布局,但如果某些东西出现在意想不到的位置,请检查您是否已为其设置了位置。
此外,请记住,当您像这样明确放置项目时,网格上的项目可能会重叠。重叠的项目可以创建一些不错的效果,但是,如果您指定了错误的起始线或结束线,也可能会导致不正确的重叠。在学习过程中,使用浏览器开发工具检查网格对于识别此类问题非常有帮助,尤其是当您的网格相当复杂时。