哈呼哈哈呼

CSS 网格布局工作草案中的点滴

哈呼哈哈呼 · 2017-02-16翻译 · 483阅读 原文链接

工具放在上面的纸质网格

网格布局规范给我们提供了一种新的布局方式,这种布局方式对现代web设计来说,更加灵活,更加适合当今web规范的发展。在今天这个web时代,随着规范的发展,最新的网格布局模块草案也有新的变化。 这篇文章,我希望通过简要地关注所有的变化来帮助大家了解最新的发展。 如果你完全没了解过网格布局或者对其中的细节不清楚,我建议你先看下我写的 网格布局引导

我们不确定如何处理margin和padding中的百分比

在开始之前,我要先告诉你一些和网格无关但十分重要并且你需要了解的一些事情。在相邻的网格项中使用的外边距不会有塌陷现象。这是因为网格项被包含在它们各自独立于其他网格项的包含块内。

现在,我们讨论下规范是如何处理margin和padding中的百分比的。当不同的网格项之间的margin和padding值为百分比时,它们可以根据网格的行内坐标轴或者各自网格项的坐标轴决定:

  • 由行内坐标轴 — 所有的 left/right/top/bottom 百分比根据grid的宽度计算。
  • 由各自网格项的坐标轴 — left/right 的百分比根据宽度计算,而top/bottom百分比按高度计算。

一些CSS和一个图表也许会让这些内容更明晰点儿。这个例子使用CSS来创建两个网格元素,且以百分比设置padding:

.grid-container {
  display: grid;
  grid-template-columns: 150px 20px 350px;
  grid-template-rows: auto;
}

.grid-element {
  background-color: #444;
  color: #fff;
  font-size: 2em;
  padding: 10%;
}

.element-a {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 2;
}

.element-b {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 2;
}

根据协议,上面的CSS创建的两个网格项。.element-a 的 top/bottom padding 值为13px(根据计算的高度130px)并且 left/right padding值为15px。同理,.element-b 的 top/bottom padding 值应为13px, left/right padding为35px。

然而,在Chrome和 Opera中,.element-a的所有的padding均为15px,.element-b的所有的margin值均为35px。在Firefox 48中,两者的padding值和规范定义的值相等,但是你得明确的设置网格行的高度。在Firefox 42中测试的结果是,padding值由网格的宽高决定而非单个元素。因此,所有的网格项拥有相同的padding。

这是个例子 如果你要在不同的浏览器中打开:

CodePen上查看SitePoint@SitePoint网格项的margins和paddings —— CSS Grid布局 的例子。

下面的图片展示了正确和现在实现方案的不同:

网格布局实现差异

如你所见,这些实现与CSSWG认为的正确的行为没有丝毫的共同点。由此可见,CSSWG还没有规范当margins和paddings的值为百分比时的情形。 CSSWG 希望浏览器们对此情形的支持尽快统一,这样规范就可以按照其中一种行为更新了。

这里,我建议开发者在设定网格项margin和padding时避免使用百分比 因为浏览器的差异表现。

拖拽工具规则

规范已经增加了重排序和可访问性相关的指南。网格布局让我们可以移动元素而不用考虑它们实际的顺序。但是,你应该负责任地使用这个特性。

grid-placement属性在不可视媒体如语音中并不影响元素的排序。同样地,视觉上重排网格项的顺序也不会影响默认的顺序导航模式的遍历顺序正如页面中通过链接实现的循环跳转。

创建网站标记时, DOM元素理想的排序是在最小屏幕上你期望它们出现的位置。在比较大的屏幕尺寸下,使用 grid-placement 属性,在视觉上更新元素的顺序。因为以前这些指南在规范中被提及过,这次它额外声明,任何使用grid-placement属性来实现合乎逻辑的排序的拖拽工具或样式表是不规范的。

遵循上述规则,你会确定非可视媒体和无CSS依据的用户代理可以依赖网页的逻辑源顺序来合理地呈现内容。

简化的子网格被提出

子网格,正如你可能猜到的,是网格中的网格。为创建一个网格项的子网格,你要用到display: subgrid属性。 如果你阅读了我的 网格布局引导,你可能已经注意到,它并没有提及子网格。这是因为纵然这个概念听起来简单,子网格的各种小细节在一个引导性教程中的一个章节中也是相当难解释清楚的。它更难实现。

因此,还没有web引擎和polyfill支持子网格。如果你有兴趣学习,你可以看看 介绍子网格的优秀文章。为了保持发展,一个删减版的子网格的建议已经被提出。它要求实现者遵循下面列出的规则和建议。

从现在开始,子网格在它的父网格中以一个普通的网格项来布局自己。 网格项的位置也应该在设置大小之前。为了设置大小,子网格会按照它是完全空的来设置,并且只占用它的border,margin,padding这些属性定义的空间。

子网格的网格项自身的大小会按照它们实际上是其父元素的网格项而来设置。然而,如果子网格的网格项被放置在子网格的第一或最后一个轨道,它的表现就好像它有一个额外的margin在一个边界等于另一个边界的margin+border+padding。这有时候可能导致子网格中的元素不能正确对齐,但是由于父网格的影响,元素仍会被合理地对齐。

不止一个精简版被提出。现在,你可以把 grid-template-columnsgrid-template-rows 这些属性的值设置为subgrid。按这种方式,你只能在一个方向创建子网格。例如,如果你将 grid-template-columns 设置为 subgrid,列的大小将由在主网格中定义的轨道的大小决定,而行的大小是自动的。

现在, subgrid 可能变成了布局方式的一个取值,而不是一个grid-template-* 值。这样,单一坐标轴的子网格布局是不被允许的。假使一个子网格不是其父网格的网格项,它的 display 值会经过计算被设置为grid

隐式网格行数的新计数规则

在我们深入之前,我先解释下隐式网格和显式网格的区别:

  • 显式网格 —grid-template-rowsgrid-template-columnsgrid-template-areas等属性定义为一个固定个数的轨道而形成的为显式网格。你自己定义值创建的网格。
  • 隐式网格 — 如果把一些网格项放置在此网格的边界外,网格容器会通过给此网格增加隐式的网格线而形成隐式的网格轨道。这些围绕显式网格的线形成了隐式网格。

考虑以下CSS:

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

.element-b {
  grid-column-start: 2;
  grid-column-end: 6;
  grid-row-start: 1;
  grid-row-end: 2;
}

这里,我用grid-templste-columns明确规定了网格前三列的宽度。其余列的宽度在用到时,每一个均等于100px。元素B的列的起始线为2,终止线为6。由于原始的网格没有6列,浏览器会自动创建剩余的列来适应.element-b。完整的网格结构包括浏览器创建的网格形成了隐式的网格:

Grid Layout implicit grid example

你可以看下下面这个CodePen上的关于隐式网格的例子,可以尝试下不同的取值:

CodePen 上查看来自 SitePoint (@SitePoint)的例子显式和隐式网格——CSS网格布局

在创建这些显式网格时,会出现一些隐藏的又可能出问题的边界情况。因此,确定隐式网格的列数的规则应该考虑到所有的情况。

起先,隐式网格的列数取以下情况的最大值:

  • 显式网格的列数
  • 所有网格项的最大列的跨度
  • 在有确定列位置的所有网格项中最大正列的结束网格线的序号减1

在网格布局最新的变化中,为了容纳所有具有确定列位置的网格项,你现在得以显式网格的列开始,然后在隐式网格的开始或结束添加列。最后,如果所有网格项中没有确定列位置中最大列跨度比隐式网格的宽度还大的话,我们要在隐式网格的结尾增加列来适应列的跨度。 另一个变化是,网格项现在应在隐式网格中被自动定位,而不是在显式网格中。

其他变化

还有一些微小的改变:

  • 规范规定负gutter值是非法的并且在碎片分裂处的gutter应该省略。在网格列之间的碎片分裂现在仍是被允许的。
  • 早期,规范提到如果一个网格项的位置包含两条线并且起始线比终止线更远,那么这两条线应当交换。 规范中没有提到当起始线和终止线相等时如何处理。最新版的草案声明在这种情况下,终止线应当被移除。
  • 规范也定义了一个更好的 网格简化语法 来让我们在一个声明中设置所有的显式和隐式网格属性以及gutter属性。

最后的想法

以上这些是目前网格布局工作草案中主要的变化!子网格领域正如期望地那样在改变并且随着深入的探讨演化地相当快。如果你想要更多的了解,你可以在网格布局模块的草案 中重温下所有变化的总结。我期望以上的解释可以帮助你对网格布局的发展趋向有些许的了解。

记住,网络发展的未来对开发者是开放的,所以,如果你对此模块有任何的想法,你可以通过filing an issue in GitHub 反馈给CSSWG或者发送邮件给archived 并用规范码[css-grid]抄送 www-style@w3.org 且你的评论话题写在第二行。你也可以给此模块的其中一个作者发邮件让他们反馈你的建议。

译者哈呼哈哈呼尚未开通打赏功能

相关文章