css subgrid 正在慢慢进入浏览器。CSS 工作组正在积极开展这项工作, 相关的 W3C 规范 已经达到了 2 级。这个新功能将使我们能够使用继承其父网格的网格轨迹并与之无缝对齐的子网格来增强网格项。
由于浏览器尚未实现CSS 子网格,本文仅对即将推出的功能进行高级概述。Subgrid 可能很快就会由 Firefox Nightly 实现,您可以在其中进行试验。请注意,规格尚未最终确定,因此未来功能仍可能发生变化。
CSS Subgrid 解决的问题:继承
只有网格容器的直接子元素成为 CSS 网格布局的一部分。网格项的子项不继承网格布局。而不是display: grid,它们的默认display属性将是block或inline,这取决于它们是块元素还是内联元素。
不属于网格的孙元素确实有几个优点。例如,他们可以自由地实现另一个布局模块,例如 flexbox,或者他们自己的具有不同对齐规则的独立网格。
但是,在许多情况下,您可能希望创建一个从父网格继承行、列和行的子网格。使用 CSS 工作组更准确的措辞:
“... 子网格轴是将其网格线与元素父网格中的线匹配的轴...”
和
“...通过与父网格的集成来得出其轨道的大小。”
现在,我们只能使用嵌套网格来模拟类似子网格的行为。然而,虽然即将到来的 CSS 子网格将具有与其父网格相同的网格轨道,但当前可用的嵌套网格并非如此。
让我们看一个示例,以更好地理解嵌套网格和 CSS 子网格之间的不同之处。
1.嵌套网格
这是一个非常简单的嵌套网格:
<div class="grid">
<div class="nested-grid">
<div class="item"></div>
</div></div>
外.grid 容器有五列三行。我已将其高度设置为 300px,以便我也可以将分数单位用于网格行:
.grid {
background-color: deepskyblue;
height: 300px;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(3, 1fr);
}
嵌套网格占用三列(网格列线 2 和 5 之间)和两行(网格行线 1 和 3 之间)。它还从外部网格继承grid-template-columns和继承:grid-template-rows
.nested-grid {
background-color: mediumblue;
grid-column: 2 / 5;
grid-row: 1 / 3;
display: inherit;
grid-template-columns: inherit;
grid-template-rows: inherit;
}
嵌套网格内的项目占用一列(网格列第 2 和 3 行之间)和两行(网格行第 1 和 3 行之间;规则继承自.nested-grid):
.item {
background-color: black;
grid-column: 2 / 3;
grid-row: inherit;
}
现在,如果您在浏览器的开发人员工具中打开网格检查器,您将立即看到问题。即使嵌套网格继承了父网格的行和列大小,两个网格的轨道仍然相互独立:
父网格有五个等宽列和三个等高行:
嵌套网格也有五个等宽列和三个等高行,但是它们完全独立于父网格的行和列:
除此之外,该.item元素使用内部网格的轨道而不是外部网格。
See the Pen CSS Grid - Nested Grid by Envato Tuts+ (@tutsplus) on CodePen.
使用 CSS 子网格,我们将能够实现不同的结果。子网格将在其跨越的区域上使用父网格的轨道,因此只有一组轨道供两个网格使用。
2. 子网格模拟(仍然是嵌套网格)
由于浏览器尚未实现 CSS 子网格,我创建了一个子网格模拟,它使用当前可用的语法来实现与即将到来的子网格类似(但不完全相同)的行为。
然而,模拟和真实的子网格之间有一个重要的区别。尽管模拟创建的内部网格看起来与父网格具有相同的网格轨迹,但它们仍然是两个独立的网格,彼此不相关。
例如,如果较大的项目溢出模拟子网格内的行或列,则所属的网格线将远离其原始位置。还可以看到模拟的子网格完全独立于父网格,因为它们不会一起移动(就像真正的子网格一样)。
模拟子网格的标记与之前相同:
<div class="grid">
<div class="subgrid">
<div class="item"></div>
</div>
</div>
属于父网格的 CSS 也是相同的,但是我创建了一个--gridheight变量,以便以后可以计算内部网格的轨道大小:
:root {
--gridheight: 300px;
}
.grid {
background-color: deepskyblue;
height: var(--gridheight);
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(3, 1fr);
}
子网格跨越与之前相同的区域,由grid-column: 2 / 5;和grid-row: 1 / 3;规则定义。
该grid-template-columns属性定义了三列而不是五列,因为我们希望将子网格的列精确地放置在父网格的列之上。
该grid-template-rows属性有一些非常丑陋calc()的规则来模拟父网格行的位置。首先,我们计算 的三分之二--gridheight,因为子网格仅跨越两行而不是三行(由grid-row规则定义)。然后,我们将其进一步除以 2,因为子网格应该分成两个等高的行。
.subgrid {
background-color: mediumblue;
grid-column: 2 / 5;
grid-row: 1 / 3;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, calc((var(--gridheight) * 2 / 3) / 2));
}
对于.item元素,我们使用与之前相同的规则,以便我们可以比较覆盖区域如何变化:
.item {
background-color: black;
grid-column: 2 / 3;
grid-row: inherit;
}
而且,成功!网格检查器显示模拟的子网格与父网格具有完全相同的网格线:
父网格仍然像以前一样有五个等宽列和三个等高行:
但是现在,内部网格线与父网格线相同:
元素的形状 .item 也发生了变化。由于内部网格现在只有两行, .item 跨越子网格的整个高度,因为它被定义为覆盖第 1 行和第 3 行之间的两行 ( grid-row: 1 / 3;)。
See the Pen CSS Grid - Subgrid Simulation by Envato Tuts+ (@tutsplus) on CodePen.
您可能已经注意到内部和外部网格使用不同的行号。即将到来的子网格也将以相同的方式计算网格线。它将在其跨越的区域上从数字 1 开始计算自己的网格线。因此,我们不必追溯父网格的行号,因此将项目放置在子网格上会更容易。
CSS 子网格语法
二维子网格
二维子网格继承父网格的行和列。因此,我们需要将subgrid值分配给grid-template-columns和grid-template-rows属性。这就是上面的代码使用新的子网格语法的样子:
.subgrid {
background-color: mediumblue;
grid-column: 2 / 5;
grid-row: 1 / 3;
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
}
新语法将为我们节省大量时间,因为我们不必计算grid-template-columnsand的值grid-template-rows。此外,子网格将绑定到父网格,因为它们将使用相同的网格轨迹。因此,如果我们向父网格或子网格添加更大的元素,它们的轨迹将一起增长。
一维子网格
CSS 子网格的最佳特性可能是我们不必在二维中使用它,但我们也可以创建仅列子网格和仅行子网格。
1. 仅列子网格
仅列子网格仅继承父网格的列,但行是独立定义的。因此,我们只需要将subgrid值分配给 grid-template-columns 属性。例如:
.subgrid {
background-color: mediumblue;
grid-column: 2 / 5;
grid-row: 1 / 3;
display: grid;
grid-template-columns: subgrid;
grid-template-rows: 1fr 2fr 3fr;
}
子网格的列使用父网格的轨道和网格线,而行表现为单独的实体。
2. 仅行子网格
类似地,仅行子网格仅继承父网格的行,但列是单独定义的。在这种情况下,我们只需要使用 属性subgrid上的值 。grid-template-rows例如:
.subgrid {
background-color: mediumblue;
grid-column: 2 / 5;
grid-row: 1 / 3;
display: grid;
grid-template-columns: 3fr 2fr 1fr;
grid-template-rows: subgrid;
}
访问一维子网格将使 CSS 子网格非常灵活,我们可以期待在未来看到很多有趣的用例。
CSS子网格的特点
CSS subgrid 有多种特性,您可以在 Grid Layout Module 的Level 2 文档中浏览。为了节省您的时间,以下是 CSS 子网格最重要的功能(请记住,它们将来可能仍会更改):
CSS子网格...
继承父网格的 命名网格线 ,
继承父网格的 命名网格区域 ,
继承父网格的间隙,
可以定义自己的命名网格线,这些网格线将添加到父节点的命名网格线中,
可以定义自己的命名网格区域,这些区域将添加到父节点的命名网格区域中,
可以覆盖继承的空白,
从 1 开始计算行号(上面已经提到过)。
结论
CSS subgrid 仍在开发中,但我们可以期待它在不久的将来被预发布版本的浏览器采用。这个高度需求的新功能将允许网格项的子项从其祖父级继承网格布局,在两个(行 和 列)或一个(行 或 列)维度上。
- 1.嵌套网格
- 2. 子网格模拟(仍然是嵌套网格)
- 二维子网格
- 一维子网格
- 1. 仅列子网格
- 2. 仅行子网格