grid-row-start

Avatar of Mojtaba Seyedi
Mojtaba Seyedi

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

grid-row-start CSS 属性是 CSS 网格布局规范 的一部分,用于指示网格项目在网格布局中开始的网格行线。此属性(以及其他基于线的网格放置属性)控制网格项目的大小及其在网格上的位置。

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

.grid-item:nth-child(2) {
  grid-row-start: 2; /* Item starts on the second row line */
}

根据 CSS 网格的默认自动放置行为,此示例中网格的第二个子元素应放置在第一行和第二列。但是,我们在第二行网格线上声明了 grid-row-start 位置,将网格项目移动到第二行并将它的起始边与第二行网格线对齐。

A three by three grid of white numbered rectangles against an orange background.
使用 grid-row-start CSS 属性将第二个网格项目移到第二行。

语法

grid-row-start: <grid-line>
完整定义
where
<grid-line> =
  auto |
  <custom-ident> |
  [ [ <integer [−∞,−1]> | <integer [1,∞]> ] && <custom-ident>? ] |
  [ span && [ <integer [1,∞]> || <custom-ident> ] ]
  • 初始值:auto
  • 应用于:网格项目和其包含块是网格容器的绝对定位框
  • 继承:
  • 计算值:指定值
  • 动画类型:离散


/* Keyword value */
grid-row-start: auto;

/* <custom-ident> value */
grid-row-start: myLineName;
grid-row-start: myGridArea;

/* <integer> + <custom-ident> values */
grid-row-start: 3;
grid-row-start: -2;
grid-row-start: main-area 2;
grid-row-start: 3 product-start;

/* span + <integer> + <custom-ident> values */
grid-row-start: span 3;
grid-row-start: span main;
grid-row-start: span myarea 5;

/* Global values */
grid-row-start: inherit;
grid-row-start: initial; /* same as `auto` */
grid-row-start: revert;
grid-row-start: revert-layer;
grid-row-start: unset;

auto

这是默认值。它指示默认跨度(1)和自动放置行为,这意味着网格项目会自动放置在下一个可用的空网格单元格中。

<custom-ident>

此语法允许您使用整数引用编号的网格线,或使用字符串引用 命名网格线命名网格区域。换句话说,您可以通过其数字索引名称指定网格线到网格项目的起始边。

按行号定位项目

在每个网格轨道之前和之后有两条网格线,并自动分配了数字索引,从数字 1 开始。

该图仅显示行网格轨道的索引。

在本文的第一个示例中,我们使用此语法通过其索引(2)引用第二条网格线,以使用 <custom-ident> 语法将网格项目的起始边与第二行的起始边对齐。

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

请注意,您还可以使用负数(例如 -1)引用网格线,但请记住,它是从网格的结束边开始计数的。以下代码指向前一个示例中的同一网格线,但反向计数。

.grid-item:nth-child(2) {
  grid-row-start: -3; /* same as 2 */
}

请注意,负整数和正整数都已分配给我们的网格。

A three by three grid of white numbered rectangles against an orange background. The first item in the second row is green.
使用 grid-row-start CSS 属性将第二个网格项目移到第二行。
按行名定位项目

您可以使用 grid-template-columnsgrid-template-rows 为网格线分配自定义名称,并使用基于线的网格放置属性按其名称引用该线。

让我们回到我们的示例,并为其所有行轨道线命名,如下面的声明所示。

.grid {
  display: grid;
  grid-template-rows: [first] 100px [second] 100px [third] 100px [last];  
  grid-template-columns: 1fr 1fr 1fr;
}

我们可以通过自定义名称而不是索引来引用第二行。

.grid-item:nth-child(2) {
  grid-row-start: second; /* same as index number 2 */
}

请注意,<custom-ident> 不能采用 span 值,因为 span 是网格放置属性的保留关键字(例如 grid-column: 1 / span 2)。

按网格区域定位项目

当使用grid-template-areas 属性定义网格区域时,您会免费获得隐式线名称,这些名称基于区域的名称。例如,一个名为header的网格区域会在其之前生成一个名为header-start的线名称,在其之后生成一个名为header-end的线名称。您可以参考这些线来设置网格项目的定位。

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

或者,您可以参考区域的名称,将项目定位在名为header的区域的起始线上。

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

由于您在此示例中使用了grid-row-start属性,因此浏览器理解您希望使用header区域的header-start线;因此,它将网格项目的起始边与网格区域的起始边对齐。

以下是一个完整的示例

<body>
  <header></header>
  <main></main>
  <footer></footer>
</body>
body {
  display: grid;
  grid-template-rows: min-content 1fr min-content;   
  grid-template-areas:
    "header"
    "main"
    "footer";
}

header {
  grid-row-start: header;
}

这将<header>元素的定位设置为我们网格中的header区域。

<integer> && <custom-ident>?

这种语法允许您在存在重复名称时,通过网格线来定位网格项目。如果存在具有相同名称的网格线,则此语法有助于指定您正在引用哪条线。

.grid {
  display: grid;
  grid-template-rows: [bar] 100px [foo] 100px [bar] 150px [bar];
}

假设您想要选择第三条线,但该线与第一条和最后一条网格线具有相同的名称——它们都称为bar。由于名为bar第二条线是第三条网格线,您可以使用2将其选为起点。

.grid-item:nth-child(2) {
  grid-row-start: 2 bar; /* The second `bar` named line which is the third line */
}
A column of three rows of white rectangles. The third item is green.

请注意,顺序无关紧要,因此前面的代码也可以这样写。

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

与前面的语法类似,您可以使用负整数从网格的结束边缘开始计算网格线。在我们的示例中,如果我们想引用第一个bar,我们可以从网格的结束边缘开始计算,并将其写成这样。

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

请注意,整数值不能为零。

span && [ <integer> || <custom-ident> ]

此语法允许网格项目跨越网格轨道。它可以通过三种不同的方式指定。

如果在此语法中的任何位置都没有指定整数,则默认值为1

span <integer>

使用后跟整数的span关键字表示网格项目从特定网格线跨越的轨道数。例如,如果我们希望网格项目向其起始边跨越三个行轨道,我们可以应用以下值。

.grid-item:nth-child(2) {
  grid-row-start: span 3;
}
网格项目使用grid-row-start CSS 属性跨越三行。

当我们使用span来放置项目的起始线时,从技术上讲,它向后跨越而不是向前跨越到结束边缘,这通常是现实场景中发生的情况。

span <custom-ident>

您可以将span与网格线的名称组合起来,使网格项目扩展到指定的网格线。

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

由于网格项目的结束线已知(6),因此我们可以将项目向起始线方向扩展,直到它遇到一条名为thirdline的网格线。

A three by five grid of rectangles. The last three rectangles in the first column are green.
网格项目使用grid-row-start CSS 属性跨越网格,直到它遇到指定的名为thirdline的网格线。
span <custom-ident> <integer>

如果指定的网格线名称分配给多条网格线——换句话说,如果我们有重复命名的网格线——我们需要说明我们想要定位哪条线。为此,我们可以向我们的值添加一个整数,指定我们正在引用哪条网格线。

以下面的网格为例

.grid-container {
  display: grid;
  grid-template-rows: [y] 50px [x] 50px [x] 50px [y] 50px [x] 50px [x];
}

.grid-item:nth-child(2) {
  grid-row-start: span x 2;
  grid-row-end: 5; /* equivalent to grid-row-end: x 3; */
}

我们将网格项目的结束线设置为第五条线。然后我们希望它向起始线方向扩展,直到它遇到一条名为x的网格线。并且由于我们希望它是第二条x网格线,因此最终得到grid-row-start: span x 2

结果,我们的网格项目从第五条线开始向起始线方向扩展,如下所示。它遇到的第一条线名为y,接下来是第一条x,最后,它遇到所需的第二条名为x的线。

A two by 5 grid of white numbered rectangles. The second through fourth items in the first column are green.
使用grid-row-start CSS 属性,将网格项目的定位从第五条线回溯到第二条名为x的线,朝向项目的起始边缘。

当您希望使用网格线的名称将网格项目扩展到网格线,但您知道有多条网格线具有该名称时,此语法很有用,因此我们添加一个整数来说明我们希望使用该网格线的第N条。

定位网格项目可能会生成隐式轨道

将网格项目的定位设置为网格线的索引或显式网格中不存在的网格线的名称,将强制网格创建隐式轨道以将该位置添加到网格中。

让我们创建一个有两行的网格,并将其中项目的定位设置为不存在的行。在下面的示例中,我们只有两行,并且没有给任何网格线命名。因此,没有索引为5的行,也没有名为test的行,但我们将这些值设置为我们的属性。

.grid {
  display: grid;
  grid-template-rows: 100px 100px;
  grid-auto-rows: 100px;
}

.grid-item {
  grid-row-start: span test;
  grid-row-end: 5;
}

由于我们知道网格中有隐式轨道,并且希望它们具有一定大小以便我们能够看到它们,因此我们将grid-auto-rows属性添加到我们的代码中。

现在我们已经设置好了一切,让我们看看我们的网格发生了什么。

A single-column layout with five grid rows.
为网格定位属性赋予不存在的值会导致网格创建隐式轨道,以便能够定位我们的网格项目。

我们将grid-row-end设置为5,但我们显式网格的最后一个索引是3,因此,在网格的末尾创建了两个隐式轨道,以提供索引为5的行。另一方面,我们将grid-row-start设置为名为test的网格线。同样,由于我们的网格中没有这样的名称,并且因为我们希望该网格线与网格项目的起始边缘对齐,所以在块方向上显式网格的起始侧会创建一个隐式行轨道,并且其线是test

定位网格项目可能会导致布局中的空隙

正如您在前面的示例中可能看到的那样,基于行的定位可能会导致网格项目之间出现空白。您可以通过将grid-auto-flow属性及其dense值应用于网格容器来避免这种情况。

Two grid layouts, one showing gaps in the layout and the other without gaps due to use the grid-auto-flow CSS property's dense keyword.
grid-auto-flow CSS 属性可以填充基于行定位导致的空白。

堆叠网格项目

在跨网格定位项目时,我们可以将它们彼此堆叠或重叠。这使我们能够有时将 CSS 网格用作绝对定位的替代方案。例如,我们可以将字幕层放在图像的顶部,而无需使用position属性,如下所示。

<figure>
  <img src="image.png" alt="how dare you leave alt empty?">
  <figcaption>The caption of our image</figcaption>
</figure>
figure {
  display: grid;
}

img,
figcaption {
  grid-column-start: 1;
  grid-column-end: -1;
  grid-row-start: 1;
  grid-row-end: -1;  
}

以下是我们得到的结果。

A square image of a cabin in the mountains surrounded by mist with a gradient overlay that goes from aqua to purple. The caption is white and printed on top of the image overlay.
使用网格定位属性将元素堆叠在彼此之上。

默认情况下,网格项目按源顺序堆叠,但您可以使用z-index属性控制其级别。在下面的示例中,我们重叠了一些项目,并使用z-index属性将第二个项目提升到最高级别。

.item:nth-child(2) {
  grid-row-start: 2;
  grid-row-end: 4;
  grid-column-start: 2;
  grid-column-end: 4;
  z-index: 1;
}
A five by five grid with four overlapping rectangles stacked diagonally from the top-left corner of the grid to the bottom-right corner. The second rectangle is on top of the stack.
使用z-index CSS 属性将第二个网格项目置于堆栈顶部。

使用负索引以获得更多灵活性

在某些情况下,您希望在网格中有一个全高项目,这意味着它从第一条网格线开始,到最后一条网格线结束。例如,在四行网格中,结束行索引为5,因此您可以编写以下代码以获得全高项目。

.grid-container {
  display: grid;
  grid-template-rows: repeat(4, min-content);
}

.grid-item.full-height {
  grid-row-start: 1;
  grid-row-end: 5;
}

它运行良好,但是如果行数更改为六行会发生什么?在这种情况下,我们需要更新定位属性的索引值。

灵活的解决方案是使用负索引!

.grid-item.full-height {
  grid-row-start: 1;
  grid-row-end: -1;
}

现在,无论我们有多少行,具有full-height类的网格项目始终跨越网格。

命名区域优先于命名行

如果命名网格区域线名具有相同的名称,则放置算法将优先使用命名网格区域的行。

考虑以下示例。

.grid {
  display: grid;
  grid-template-rows: 80px [y] 80px 80px 80px 80px;
  grid-template-areas:
    "x"
    "x"
    "x"
    "y"
    "y";
}

第二条网格线名为y,最后两行定义为具有相同名称的区域。现在,要定位第一个网格项目,我们将y作为grid-row-start的值。让我们看看它将引用哪一行。

.grid-item:first-child {
  grid-row-start: y;
}

如下一张图片所示,尽管y线更靠近第一个项目,但浏览器选择了网格区域的边缘来放置项目的起始边缘。

A sngle-column layout with five rows containing white rectangles. The first item is in the fourth row and colored green.
网格区域和网格线具有相同的名称y,当您将该名称分配给网格定位属性时,浏览器会选择网格区域线而不是命名网格线。

请注意,如果您使用网格区域的隐式名称线,则不适用此规则。例如,让我们将前面示例中网格线的名称更改为y-start。此外,我们知道名为y的区域分配了y-start的隐式网格线。现在,如果我们将y-start设置为grid-row-start,则网格命名线将成为本次的获胜者。

.grid {
  display: grid;
  grid-template-rows: 50px [y-start] 50px 50px 50px 50px;
  grid-template-areas: "x"
                       "x"
                       "x"
                       "y"
                       "y";
}

.grid-item:first-child {
  grid-row-start: y-start;
}
A sngle-column layout with five rows containing white rectangles. The first item is in the second row and colored green.

可访问性

使用网格定位属性时需要注意的一件事是由重新排列项目引起的问题。当您更改项目的顺序时,只有网格项目的视觉顺序会发生更改,并且该顺序可能与原始文档顺序不同。这可能会导致在键盘上通过文档进行制表或收听以与 HTML 相同的顺序读取内容的屏幕阅读器的人员体验非常糟糕。

因此,在 HTML 元素的顺序很重要时,避免更改网格项目的顺序。例如,它可能对随机图片库有益,但对于您的表单输入可能不太好。

但是,在撰写本文时,有一个提案来解决此问题,希望将来能够解决此问题。

演示

您可以在演示中更改网格放置属性的值,以查看第三个网格项目发生了什么变化。

浏览器支持

更多信息