【译】CSS Grid布局的秘密

深入研究css grid布局规范,来揭示你可能错过的一些功能-以及一些即将推出的功能。

在撰写本文时,CSS Grid Layout于2017年3月,在浏览器中推出了,大多数网站超过70%的访问者会得到网格的支持。这个数据在迅猛的增长着,并且随着Edge发布其更新的支持,这一数字将继续增多。

我希望你已经探索了CSS Grid Layout的一些功能。这篇文章会看一些你可能错过的特性。也会看看将来的规范里会出现的一些特性。

01.minmax()函数

不像其他需要在条目上设置尺寸的布局方法那样,在Grid布局中,我们在容器级设置尺寸。我们定义创建网格单元的轨道,可以在其中放置内容。
为了能弹性化的实现这个,网格给CSS带来了新的特性。其中一个就是minmax()函数。这个函数意味着你可以为轨道指定一个最小值和最大值。

在下面的示例中,我有一个整洁的面板,左上方标题,右侧有大图。我想要顶部的最小高度为150像素,想要让那个盒子可以大到大于150像素。这里我用了minmax()函数,设置了150像素的最小值,和auto的最大值。

1
2
3
4
5
.grid {
display: grid;
grid-template-columns: 1.2fr 1fr;
grid-template-rows: minmax(150px, auto) minmax(300px,auto);
}

1-1

通过设置一行高度的最小值,即使内容更短的时候,我们也可以在设计上创建整齐的行。
1-2

设置了最大值为auto的minmax()函数,意味着如果有多的内容也不会溢出。

02.自动填充和自适应

弹性的盒子启用了响应式设计模式,无需依赖媒体查询。网格更进一步了,通过二维排列的项目,可以实现灵活的设计模式:逐行逐列的。一种有用的模式是能够容纳尽可能多的列,并且为此我们使用两个新的关键字:auto-fill和auto-fit。

要将200像素的列的轨道放入容器,使用下面的列表:

1
2
3
4
.grid1 {
display: grid;
grid-template-columns: repeat(auto-fill, 200px);
}

为使那些列弹性化,但是保持一个200像素的最小值,用上我前面贴士里面提到的minmax() 函数。我们可以创建最少200像素,最大值1fr的列。在计算错多少个200像素的列可以填充,浏览器在列之间平均分配剩余空间。

1
2
3
4
.grid1 {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, auto));
}

2-1

这个图片展示了固定尺寸列和使用最minmax()创建的同学尺寸的列的不同。

我在这里用了auto-fill的关键词;这样即使没有内容,也会为轨道留空间。如果你用auto-fit代替它,任何完全空的轨道都会被折叠,他们的空间会分配给其他轨道。

03.密集包裹模式

当你在一个元素上声明display:grid时,所有的直属子元素都会变成网格单元,单元格会自动开始布局到那个网格上。这是基于定义在规范中的自动布局规则进行的。

如果某些单元格跨越轨道,这意味着有些单元格不适配可用轨道,则它们将在网格上创建一个新行。默认情况下,网格按照它们出现在源代码中的顺序转发并显示单元格。但是,如果将网格grid-auto-flow的值设置为dense,则网格将在脱离这些间隙后开始回溯。 如果它找到了一个可以放入已经脱离的缝隙的单元格,它就会把它捡起来,并将它放在原始顺序之外,进入缝隙。

1
2
3
4
5
.grid {
display: grid;
grid-auto-flow: dense;
grid-template-columns: repeat(auto-fill,minmax(200px, 1fr));
}

3-1

自动放置规则会根据默认规则保持网格项目按源顺序显示;这可能会导致布局上有间隙。

3-2

使用grid-auto-flow为dense值时,会开启密集包裹模式,会回填布局中的间隙。

如果你的展示没有逻辑顺序,这个现象是有用的,但是,你可以很容易的用键盘为一些导航搭建一个很复杂的布局,如果他们一个挨着一个排列。谨慎用这个特性并进行测试。

04.魔法行和魔法区域

当你使用grid模板区域方法来布局内容,你在网格上创建了一个可命名的区域。这反过来为行和列创建一组命名行,这些行和列使用带有-start和-end后缀的区域名称。在下一个示例中,我使用了通过定位网格区域来定位覆盖图而创建的命名线。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.grid {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
grid-auto-rows: minmax(100px, auto);
grid-template-areas:
"sd1 content sd2"
"sd1 footer sd2";
}
.side1 { grid-area: sd1; }
.side2 { grid-area: sd2; }
.content { grid-area: content; }
.footer { grid-area: footer; }

.grid .overlay {
grid-column: sd1-start / sd2-end;
grid-row: content-start / footer-end;
}

当你使用命名的网格线时,此功能会反向作用。 如果为行和列以-start和-end结尾来命名,将会创建一个使用的主名称的命名区域。

由行和列的属性content-start和content-end定义的区域将具有名称内容。 你可以在那个区域放置一个grid-area:content的单元格。

4-1

覆盖层已经通过使用从区域名称创建的命名属性,被放置在网格区域的顶部。

05.默认的对准方式

当一个单元格变成网格单元时,默认的行为是拉伸铺满其网格区域;除非单元格是具有内在长宽比的东西。 如果单元具有长宽比,则它将在行和列方向上与起始线对齐。 这意味着Grid默认不会拉伸你的图像,尽管你可以通过改变对齐行为来做到这一点。

06.回退

写入CSS网格规范的是CSS网格布局如何覆盖其他布局方法的细节。 如果你有一个浮动项目,使用display:table或display:inline块,然后变成一个网格单元,该规范将解释将会发生什么。

简而言之,当一个单元变成一个网格单元时,你会发现:

如果它是浮动的,或使用clear属性,则这些属性将停止影响该单元。
如果它具有display:inline-block或使用table属性,如display:table-cell,则不再适用。
在表格属性的情况下,不再创建使用display:table-cell时没有父表格的匿名框。
垂直对齐不再适用。
我创建了一个使用示例详细说明这些覆盖的备忘录。 你可以在我的网站上找到。

在许多情况下,依靠这种压倒性的行为会起作用,但需要注意后来成为网格项目的单元上设置的宽度。 在之前的布局方法中,我们控制项目上单元的宽度。

使用网格,我们将该单元放入限制网格的网格单元中。 这意味着如果您有一个设置了百分比宽度的单元,那么一旦项目成为网格单元,该宽度将解析为网格区域的百分比。

这个解决方案是另一个CSS规范:功能查询。 我们可以使用功能查询来测试网格布局支持。 如果浏览器支持Grid,我将宽度设置为auto。

1
2
3
4
5
6
7
8
9
.grid > div {
float: left;
width: 33.333%;
}
@supports (display: grid) {
.grid > div {
width: auto;
}
}

07.用min-content max-content设置尺寸

CSS内部和外部大小调整模块3级规范定义了用于调整大小的其他关键字。 这些关键字包括最小内容和最大内容,可用于定义网格轨道中的大小。

看一个非常简单的例子,我创建了一个双列轨道网格。 一列被定义为min-content大小,第二列max-content。 第一个轨道只有显示内容的单个词所需的大小 - 这是此轨道的最小尺寸。 第二个扩展以允许显示整行,这可能会导致需要管理和处理的溢出。

1
2
3
4
.grid {
display: grid;
grid-template-columns: min-content max-content;
}

7-1

min-content列显示一个单词的宽度,max-content列扩展以适应句子的展示。

Level 2 特性

网格规范现在处于候选推荐状态,这意味着我们希望不对规范做任何重大更改; 相反,它会进入一个阶段,在这个阶段中我们会查找每个功能的至少两个实现。 这确保了规范是有意义的,并且可以通过浏览器来实现。

然而,网格仍然在发生着变化,在本文的其余部分中,我们将看到最近对Level 1规范的更改以及我们在Level2中可能期待的一些事情。

08.gap在变化

在2017年8月的CSS工作组会议期间,grid-gap,加上grid-column-gap和grid-row-gap等特性发生了变化,成为gap,column-gap和row-gap。它们也被移动到Box Alignment规范中。

这是一个规范,它采用了Flexbox的良好对齐功能并进行了扩展,因此它们也可以在网格中使用 - 也可能用于其他布局方法。

将间隙特征放入Box Alignment规范中并以更通用的方式命名它们意味着它们可以用于其他布局类型,因为它们有意义。在Flexbox中,他们有意义的地方显而易见。

这种重命名意味着我们最终将在Flexbox中获得适当的gaps;没有更多的margin边缘。浏览器会将旧名称替换为新名称,因此如果您已经在网格布局中使用了gap,代码将不会中断。但是,你可能也想自己添加两个属性;浏览器会忽略不支持的属性。

09.网格不是砌体

当第一次看到本文前面展示的密集打包模式时,他们经常认为Grid可以完成砌体布局模式。 然而,砌体是一种完全不同的布局。 标准的砌体布局不是一个严格的网格,使得这种模式位于Flexbox所擅长的和Grid所做的东西之间。

然而,在CSS工作组,我们正在考虑这个问题。 这是我们知道开发人员真正想要做的事情。 您可以在GitHub上的CSS WG草稿库中找到讨论,甚至可以添加您的想法。

10.网格区域伪元素

网格布局的另一个常见功能要求是能够对网格单元格或区域进行样式设置,而无需插入元素来设置样式。 目前,要将边框添加到某个区域,需要向标记添加一个空元素或使用生成的内容创建可以样式化的网格项目。

在考虑为网格区域添加某种伪元素时出现了一个问题。 如果你想添加背景或边框到一个特定的区域而不添加额外的标记或使用生成的内容,这会给你一些东西来达到目的。

这篇文章最初出现在专业网页设计师和开发者杂志网络杂志298期 - 提供最新的网络趋势,技术和技术。 在这里购买298或在这里订阅网络。

译者:Linda

作者:Rachel Andrew

原文链接:CSS Grid Layout secrets revealed