grid-column-start

Avatar of Mojtaba Seyedi
Mojtaba Seyedi

DigitalOcean 提供适合您旅程各个阶段的云产品。立即开始使用 $200 免费信用额度!

grid-column-start CSS 属性是 CSS 网格布局规范 的一部分,用于指示网格项目在网格布局中开始的网格线。此属性——在其他基于线的网格放置属性中——控制网格项目的尺寸以及它在网格中的位置。

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

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

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

A three-by-two grid with five items.
使用 grid-column-start CSS 网格属性将第二个网格项目移到第三列。

目录

语法

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

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

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

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

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

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

auto

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

<custom-ident>

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

按线号放置项目

在每个网格轨道的前后都有两条网格线,自动为它们分配了数字索引,从数字一开始。

A three-by-two-grid with six items.

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

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

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

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

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

A three-by-two grid with five items where the second item is positioned in the third column with the grid-column-start CSS property.
使用 grid-column-start 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-start: third; /* same as index number 3 */
}

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

按网格区域放置项目

使用 grid-template-areas 属性定义网格区域时,您会免费获得 隐式线名,这些线名是根据区域的名称生成的。例如,名为 sidebar 的网格区域会在其前面生成一条名为 sidebar-start 的线,并在其后面生成一条名为 sidebar-end 的线。您可以引用这些线来设置网格项目的位置。

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

或者,您可以引用区域的名称,将项目放置在名为 sidebar 的区域的起始线处。

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

由于您在此示例中使用的是 grid-column-start 属性,因此浏览器会理解您希望将网格项目的起始边缘与 sidebar 命名区域的起始边缘对齐。

这是一个完整的示例。

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

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

这将 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第二条线是第三条网格线,因此您可以使用 2 来选择它作为起点。

.grid-item:nth-child(2) {
  grid-column-start: 2 bar; /* The second `bar` named line which is the third line */
}
A single row grid with three columns and the second item in the third column.

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

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

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

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

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

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

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

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

span <integer>

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

.grid-item:nth-child(2) {
  grid-column-start: span 3;
}
A six-by-two grid where the second item spans three columns.
网格项使用grid-column-start属性跨越三列。

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

span <custom-ident>

您可以将span与网格线名称结合使用,使网格项扩展到指定的网格线。

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

由于网格项的结束线已知(6),我们可以将项目朝向开始线跨越,直到它遇到名为thirdline的网格线。

A five-by-two grid where the third item spans three columns.
网格项使用grid-column-start CSS 属性跨越网格,直到它遇到名为thirdline的指定网格线。
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: span x 2;
  grid-column-end: 5; /* equivalent to grid-column-end: x 3; */
}

我们将网格项的结束线设置为第五条线。然后我们希望它向起始线跨越,直到它遇到名为x的网格线。由于我们希望它是第二条名为x的网格线,所以最终得到grid-column-start: span x 2

因此,我们的网格项从第五条线开始向起始线跨越,如下所示。它遇到的第一条线名为y,接下来是第一条名为x的线,最后它遇到了我们想要的第二条名为x的线。

A five-by-three grid where each row has a few empty columns.
使用grid-column-start属性设置网格项从第五条线到第二条命名线的起始边位置。

当您希望使用网格线名称跨越网格项,但您知道该名称有多条网格线时,此语法很有用,因此我们添加一个整数来表示我们想要该网格线的第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属性添加到我们的代码中。

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

A single-row grid with five columns, two of which are explicit.
给网格放置属性设置不存在的值会导致网格创建隐式轨道,以便能够定位网格项

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

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

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

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

Showing the before and after results of using a dense CSS Grid layout.
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;  
}

以下就是我们得到的结果

Cabin in the woods with a green to blue gradient overlay and the words the caption of our image on top.

默认情况下,网格项按源顺序堆叠,但您可以使用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;
}
Four overlapping grid items in a five-by-five grid.
使用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的第一条网格线是网格中最右边的线。

Two single-row grids with four columns, one showing a left-to-right writing mode and the other showing a right-to-left writing mode.
演示书写模式如何影响网格布局的方向及其网格线的索引。

因此,在使用网格线索引来定位网格项目时,例如使用 `grid-column-start` 属性,请考虑网格的书写方向。

命名区域优先于命名线

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

请考虑以下示例

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

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

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

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

网格区域和网格线具有相同的名称 `y`。当您将该名称分配给网格放置属性时,浏览器会选择网格区域线而不是命名网格线。

请注意,如果您使用网格区域的隐式名称线,则不适用此规则。例如,让我们将先前示例中网格线的名称更改为 `y-start`。另外,我们知道名为 `y` 的区域有一个分配的隐式网格线 `y-start`。现在,如果我们将 `y-start` 设置为 `grid-column-start`,网格命名线将成为这次的赢家。

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

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

可访问性

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

因此,当元素的 HTML 顺序很重要时,请避免更改网格项目的顺序。例如,这可能对随机图片库很好,但可能不适合您的表单输入。

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

演示

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

浏览器支持

更多信息