grid-column-end

Avatar of Mojtaba Seyedi
Mojtaba Seyedi

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

grid-column-end CSS 属性是 CSS 网格布局规范 的一部分,用于指示网格项目在网格布局中结束的列网格线。 此属性(以及其他基于行的网格放置属性)控制网格项目的尺寸及其在网格上的位置。

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

.grid-item:nth-child(2) {
  grid-column-end: 4; /* Item ends on the third column line */
}

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

Shifting the second grid item into the third column using the grid-column-end CSS Grid property.
使用 grid-column-end CSS 网格属性将第二个网格项目移至第三列

语法

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

/* Keyword value */
grid-column-end: auto;

/* <custom-ident> value */
grid-column-end: myLineName;
grid-column-end: myGridArea;

/* <integer> + <custom-ident> values */
grid-column-end: 3;
grid-column-end: -2;
grid-column-end: main-area 2;
grid-column-end: 3 sidebar-start;

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

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

auto

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

<custom-ident>

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

通过行号定位项目

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

在这篇文章的第一个示例中,我们使用此语法通过索引 (4) 引用第四条网格线,以使用 <custom-ident> 语法将网格项目的结束边缘与第三列的起始边缘对齐。

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

您也可以使用负数来引用网格线,但请记住,它是从网格的结束边缘开始计数。 以下代码指向上一示例中的同一网格线,但反向计数

.grid-item:nth-child(2) {
  grid-column-end: -1; /* same as 4 */
}

请注意,负整数与正整数一起分配给我们的网格

Shifting the second grid item into the third column using the grid-column-end CSS Grid property.
使用 grid-column-end CSS 网格属性将第二个网格项目移至第三列
通过行名定位项目

您可以使用 grid-template-columnsgrid-template-rows 将自定义名称分配给网格线,然后使用基于行的放置网格属性通过其名称引用该线。

让我们回到我们的示例,并将所有列轨道线命名为以下声明

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

我们可以通过自定义名称而不是索引引用第四条线

.grid-item:nth-child(2) {
  grid-column-end: last; /* same as index number 4 */
}

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

通过网格区域定位项目

使用 grid-template-areas 属性定义网格区域时,您可以免费获得 隐式行名,这些行名基于区域的名称。 例如,名为 sidebar 的网格区域会生成名为 sidebar-start 的行名,它之前还有一个名为 sidebar-end 的行名。 您可以引用这些行来设置网格项目的位置。

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

或者,您可以引用区域的名称,将项目定位在名为 sidebar 的区域的结束行处

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

由于在此示例中我们使用的是 grid-column-end 属性,因此浏览器理解我们希望 sidebar 命名区域的 sidebar-end 行; 因此,它将网格项目的结束边缘与网格区域的结束边缘对齐。

这是一个完整的示例

<body>
  <main></main>
  <aside></aside>
</body>
body {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;   
  grid-template-areas: "main main sidebar";
}

aside {
  grid-column-end: sidebar-end;
}

这将 aside 元素的位置设置为网格中的 sidebar 区域。

<integer> && <custom-ident>?

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

.grid {
  display: grid;
  grid-template-columns: [bar] 1fr [foo] 1fr [bar] 300px [bar];

  /*
    Using repeat() function also gives you repeated named grid line, for example:
    grid-template-columns: repeat(3, [bar] 1fr);
  */
}

假设您要选择第四条线,但该线与第一条线和第三条网格线的名称相同——它们都称为 bar。 由于名为 bar第三条线是您要选择的第四条线,因此您可以使用 3 来选择它作为结束点

.grid-item:nth-child(2) {
  grid-column-end: 3 bar; /* The third `bar` named line which is the fourth line */
}

请注意,顺序无关紧要,因此我们也可以像这样编写上一段代码

.grid-item:nth-child(2) {
  grid-column-end: bar 3;
}

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

.grid-item:nth-child(2) {
  grid-column-end: -3 bar;
}

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

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

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

请注意,如果此语法中没有指定整数,则默认值为 1

span <integer>

使用 `span` 关键字后跟一个整数表示网格项从特定网格线跨越的轨道数量。例如,如果我们希望网格项向其结束边缘跨越三个列轨道,我们可以应用以下值

.grid-item:nth-child(2) {
  grid-column-end: span 3;
}
The grid item spans 3 columns using the grid-column-end property.
网格项使用 `grid-column-end` 属性跨越三个列。
span <custom-ident>

可以将 `span` 与网格线名称组合使用,使网格项扩展到指定的网格线为止。

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

由于网格项的起始线是已知的 ( `3` ),因此可以将项向结束线扩展,直到它到达名为 `lastline` 的网格线为止。

The grid item spans across the grid until it hits the specified grid line named "lastline" using the grid-column-end property.
网格项使用 `grid-column-end` 属性跨越网格,直到遇到名为“lastline”的指定网格线为止。
span <custom-ident> <integer>

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

以以下网格为例

.grid-container {
  display: grid;
  grid-template-columns: [y] 1fr [x] 1fr [x] 1fr [y] 1fr [x] 1fr [x];
}

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

我们将网格项的起始线设置为第二条线。然后我们希望它向前扩展,直到它遇到一条名为 `x` 的网格线。并且由于我们希望它是第二个 `x` 网格线,我们最终得到了 `grid-column-end: span x 2`。

结果,我们的网格项从第二条线开始向结束线扩展,如下图所示。它遇到的第一条线是第一个 `x`,接下来是名为 `y`,最后它遇到了我们想要的第二个名为 `x` 的线。

Setting the position of a grid item from the second line to the second x named line using grid-column-end property.
使用 `grid-column-end` 属性设置网格项从第二条线到第二个名为 `x` 的线的位置。

这种语法在您希望使用名称将网格项跨越到网格线时很有用,但您知道有多条网格线具有相同的名称,因此我们添加一个整数来表示我们要使用该网格线的第 `N` 条。

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

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

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

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

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

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

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

Giving grid placement properties any values that do not exist causes the grid to create implicit tracks to position our grid item.
为网格放置属性提供任何不存在的值会导致网格创建隐式轨道以定位我们的网格项。

我们将 `grid-column-end` 设置为 `5`,但我们的显式网格的最后一个索引是 `3`,因此,在网格的末尾创建了两个隐式轨道,以便我们获得索引为 `5` 的线。另一方面,我们将 `grid-column-start` 设置为名称为 `test` 的网格线。同样,由于我们的网格中没有这样的名称,并且因为我们希望该网格线与网格项的起始边缘对齐,所以会在显式网格的起始侧(内联方向)创建了一个隐式列轨道,它的线是 `test`。

定位网格项可能会导致出现空洞。

正如您可能在前面的示例中看到的,基于行的定位会导致网格项之间出现空白。

如果这些空洞在您的设计中不受欢迎,我们可以通过将 `grid-auto-flow` 属性与 `dense` 值一起应用于网格容器来轻松地处理它们。

The grid-auto-flow property can fill empty spaces caused by line-based positioning.
`grid-auto-flow` 属性可以填充基于行的定位造成的空洞。

堆叠网格项

在跨网格定位项目时,可以将它们堆叠或彼此重叠。这使我们能够将 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;  
}

这就是我们的结果

Stacking elements on top of each other using grid placement properties.
使用网格放置属性将元素彼此堆叠。

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

.item:nth-child(2) {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 2;
  grid-row-end: 4;
  z-index: 1;
}
Bringing the second grid item to the top of the stack using the z-index property.
使用 `z-index` 属性将第二个网格项提升到堆栈顶部。

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

在某些情况下,您可能希望在网格中使用一个全宽项目,这意味着它从第一个网格线开始并以最后一个网格线结束。例如,在一个四列网格中,结束线的索引是 `5`,因此您可以编写以下代码来拥有您的全宽项目。

.grid-container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

.grid-item.full-width {
  grid-column-start: 1;
  grid-column-end: 5;
}

它运行良好,但如果列数更改为六个会怎样?在这种情况下,我们需要更新放置属性的索引值。

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

.grid-item.full-width {
  grid-column-start: 1;
  grid-column-end: -1;
}

现在,无论我们有多少列,具有 `full-width` 类别的网格项总是会跨越整个网格。

网格线索引取决于书写模式。

整个网格布局模块都是基于文档的书写模式;因此,网格线也取决于方向和书写模式。例如,在波斯语和阿拉伯语等从右到左的语言中,索引为 `1` 的第一条网格线是网格中最右边的线。

Demonstrating how the writing mode affects the direction of a grid layout and indexes of its grid lines.
演示书写模式如何影响网格布局的方向及其网格线的索引。

因此,在使用网格线索引使用 `grid-column-end` 等属性定位网格项时,请考虑您的网格的书写方向。

命名区域优先于命名行。

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

考虑以下示例

.container {
  display: grid;
  grid-template-columns: 1fr [y] 1fr 1fr 1fr 1fr;
  grid-template-areas: "x x x y y";
}

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

.grid-item:first-child {
  grid-column-end: y;
}

正如您在下一张图片中看到的,虽然 `y` 线更靠近第一个项目,但浏览器选择了网格区域的边缘来放置项目的结束边缘。

A grid area and a grid line have the same name, y, and the browser selects the grid area line over the named grid line when that name is assigned using grid placement properties.
网格区域和网格线具有相同的名称 `y`,当使用网格放置属性分配该名称时,浏览器会选择网格区域线而不是命名网格线。

请注意,如果您使用网格区域的隐式命名行,则此规则不适用。例如,让我们将上一个示例中的网格线名称更改为y-end。此外,我们知道名为y的区域有一个隐式的y-end网格线分配。现在,如果我们将y-end设置为grid-column-end,那么这次名为y-end的网格线将胜出。

.container {
  display: grid;
  grid-template-columns: 1fr [y-end] 1fr 1fr 1fr 1fr;
  grid-template-areas: "x x x y y";
}

.grid-item:first-child {
  grid-column-end: y-end;
}

无障碍性

在使用网格定位属性时需要注意的一点是,重新排列项目会导致的问题。当您更改项目的顺序时,只有网格项目的视觉顺序会发生改变,而该顺序可能与原始文档顺序不一致。这可能会导致用户在键盘上按 Tab 键浏览文档,或使用按照 HTML 顺序读取内容的屏幕阅读器时体验极差。

因此,在 HTML 元素顺序很重要的情况下,请避免更改网格项目的顺序。例如,这可能适用于随机图片库,但不适用于您的表单输入。

然而,在撰写本文时,有一个提案来解决这个问题,希望将来能解决这个顾虑。

演示

您可以在演示中更改网格定位属性的值,以查看第三个网格项目会发生什么。

浏览器支持

更多信息