如果你喜欢阅读发布说明,那么你可能已经在 Firefox 70 说明 中发现了一行关于 display CSS 属性 的双值语法的实现。或者你可能在昨天的 Firefox 70 汇总文章 中看到了提到。今天我将解释这意味着什么,以及为什么理解这种双值语法很重要,尽管它目前只在 Firefox 中有实现。
display 属性
display 属性是我们用来改变元素及其子元素的格式化上下文的方法。在 CSS 中,某些元素默认情况下是块级元素,而其他元素是内联元素。这是你学习 CSS 的第一件事之一。
display 属性允许在这些状态之间切换。例如,这意味着 h1(通常是块级元素)可以以内联方式显示。或者 span(最初是内联元素)可以作为块级元素显示。
最近我们获得了 CSS 网格布局 和 Flexbox。为了使用这些,我们也使用 display 属性的值——display: grid 和 display: flex。只有当 display 的值改变时,子元素才会变成 Flex 或网格项,并开始响应网格或 Flexbox 规范中的其他属性。
双值显示——带 display: flex 的 span
然而,网格和 Flexbox 所展示的是,一个元素既有外部显示类型,也有内部显示类型。当我们使用 display: flex 时,我们创建一个块级元素,它包含 Flex 子元素。子元素被描述为参与 Flex 格式化上下文。如果你使用 display: flex 对 span 进行操作,你就会看到这一点——span 现在是块级元素。它在与布局中其他框的关系中表现得像块级元素一样。就好像你对 span 应用了 display: block 一样,但是我们也获得了子元素行为的改变。在下面的 CodePen 中,你可以看到文本串和 em 已经变成了两个 Flex 项。
查看 CodePen
Mozilla Hacks 双值显示:带 display: flex 的 span,作者是 rachelandrew (@rachelandrew)
在 CodePen 上。
双值显示——带 display: grid 的 span
网格布局的行为方式相同。如果我们使用 display: grid,我们将创建一个块级元素和一个用于子元素的网格格式化上下文。我们还有方法可以使用 display: inline-flex 和 display: inline-grid 创建一个内联级框,其中包含 Flex 或网格子元素。下一个示例展示了一个 div(通常是块级元素)如何表现为一个具有网格项子元素的内联元素。
作为内联元素,框不会占用内联尺寸中的所有空间,并且接下来的文本串会显示在它旁边。然而,子元素仍然是网格项。
查看 CodePen
Mozilla Hacks 双值显示:inline-grid,作者是 rachelandrew (@rachelandrew)
在 CodePen 上。
重构 display
如以上示例所示,元素的外部 display 类型始终是块级或内联级,并决定框在文档的正常流中的行为方式。然后,内部 display 类型改变子元素的格式化上下文。
为了更好地描述这种行为,CSS Display 规范已重构,允许 display 接受两个值。第一个值描述外部 display 类型是块级还是内联级,而第二个值描述子元素的格式。此表显示了这些新值如何映射到规范中的单值(现在称为传统值)。
| 单值 | 新值 |
|---|---|
| block | block flow |
| flow-root | block flow-root |
| inline | inline flow |
| inline-block | inline flow-root |
| flex | block flex |
| inline-flex | inline flex |
| grid | block grid |
| inline-grid | inline grid |
display 还有更多值,包括列表和表格;要查看所有值,请访问 CSS Display 规范.
我们可以看到这对 Flexbox 如何起作用。如果我想让一个块级元素包含 Flex 子元素,我会使用 display: block flex,如果我想让一个内联级元素包含 Flex 子元素,我会使用 display: inline flex。以下示例将在 Firefox 70 中起作用。
查看 CodePen
Mozilla Hacks 双值显示:两个 Flex 值,作者是 rachelandrew (@rachelandrew)
在 CodePen 上。
我们可靠的 display: block 和 display: inline 也没有被遗忘,display: block 变成了 display: block flow——即一个包含在正常流中的子元素的块级元素。display: inline 元素变成了 display: inline flow。
display: inline-block 和 display: flow-root
如果我们查看 display 的几个值——一个新值,一个可以追溯到 CSS2 的值,这一切就会变得更加有趣。CSS 中的内联框设计为位于行框内,行框是包裹句子中每一行文本的匿名框。这意味着它们的行为方式有所不同:如果你对内联框的所有边缘添加填充,例如在下面的示例中,我对内联元素添加了背景颜色,则会应用填充。然而,它不会将块方向上的行框推开。此外,内联框不尊重宽度或高度(或内联尺寸和块尺寸)。
使用 display: inline-block 会使内联元素包含此填充,并接受宽度和高度属性。然而,它仍然是一个内联元素;它继续位于文本流中。
在下一个 CodePen 中,我有两个 span 元素,一个是普通的内联元素,另一个是内联块元素,这样你就可以看到此值导致的布局差异。
查看 CodePen
Mozilla Hacks 双值显示:inline-block,作者是 rachelandrew (@rachelandrew)
在 CodePen 上。
然后我们可以看看 display 的新值 flow-root。如果你对元素赋予 display: flow-root,它会变成一个新的块级格式化上下文,成为新正常流的根元素。本质上,这会导致浮动元素被包含。此外,子元素上的边距会保留在容器内,而不是与父元素的边距合并。
在下一个 CodePen 中,你可以比较第一个示例(没有 display: flow-root)和第二个示例(有 display: flow-root)。第一个示例中的图片会从框的底部伸出来,因为它已被从正常流中移除。浮动元素被移出流并缩短了跟随内容的行框。然而,实际的框不会包含该元素,除非该框创建了一个新的块级格式化上下文。
第二个示例确实具有 flow-root,你可以看到带有灰色背景的框现在包含了浮动元素,在文本下方留下了空白。如果你曾经通过将 overflow 设置为 auto 来包含浮动元素,那么你是在实现相同的效果,因为除了默认的 visible 之外的 overflow 值会创建一个新的块级格式化上下文。但是,可能会有一些额外的意外影响,例如阴影裁剪或意外滚动条。使用 flow-root 使你能够创建 块级格式化上下文 (BFC),而不会发生其他任何事情。
查看 CodePen
Mozilla Hacks 双值显示:flow-root,作者是 rachelandrew (@rachelandrew)
在 CodePen 上。
强调 display: inline-block 和 display: flow-root 的原因是这两者本质上是一样的。众所周知的 inline-block 值创建了一个内联 flow-root,这就是为什么新的双值版本 display: inline-block 就是 display: inline flow-root 的原因。它执行了与 flow-root 属性完全相同的任务,在双值世界中,它变成了 display: block flow-root。
你可以在最后一个示例中看到这两个值的使用,该示例使用 Firefox 70。
查看 CodePen
Mozilla Hacks 双值显示:inline flow-root 和 block flow-root,作者是 rachelandrew (@rachelandrew)
在 CodePen 上。
我们能使用这些双值属性吗?
由于目前仅在 Firefox 70 中提供支持,因此现在就开始在生产环境中使用这些双值属性还为时过早。目前,其他浏览器不支持它们。除了 Firefox 之外,要求 display: block flex 将被视为无效。由于你可以使用单值语法访问所有功能(它们将保留为新语法的别名),因此没有理由突然切换到这些属性。
但是,在 CSS 中,它们对于含义非常重要。它们恰当地解释了框与其他框的交互,包括它们是块级还是内联级,以及子元素的行为。我认为,为了理解 display 的含义和作用,它们是一个非常有用的澄清。因此,我已经开始使用这两个值来教授 display,以帮助解释当你改变格式化上下文时会发生什么。
看到新功能的实现总是令人兴奋,我希望其他浏览器也能很快实现这些双值版本。这样,在不久的将来,我们就能以与我们现在解释相同的方式编写 CSS,清晰地展示框与子元素行为之间的关系。
关于 Rachel Andrew
Rachel Andrew 是一位前后端 Web 开发人员,也是 Perch CMS 背后公司的半壁江山,同时也是 Smashing Magazine 的主编。她还是 Google 开发者专家(Web 技术),并代表 Fronteers 担任 CSS 工作组成员,在那里她还是多栏布局规范的共同编辑。她著有 22 本书,并且是全球各地会议上的常客,你可以在 https://rachelandrew.co.uk 找到她的最新动态。