CSS Display 属性的双值语法

如果你喜欢阅读发布说明,那么你可能已经在 Firefox 70 说明 中发现了一行关于 display CSS 属性 的双值语法的实现。或者你可能在昨天的 Firefox 70 汇总文章 中看到了提到。今天我将解释这意味着什么,以及为什么理解这种双值语法很重要,尽管它目前只在 Firefox 中有实现。

display 属性

display 属性是我们用来改变元素及其子元素的格式化上下文的方法。在 CSS 中,某些元素默认情况下是块级元素,而其他元素是内联元素。这是你学习 CSS 的第一件事之一。

display 属性允许在这些状态之间切换。例如,这意味着 h1(通常是块级元素)可以以内联方式显示。或者 span(最初是内联元素)可以作为块级元素显示。

最近我们获得了 CSS 网格布局Flexbox。为了使用这些,我们也使用 display 属性的值——display: griddisplay: 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-flexdisplay: 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: blockdisplay: inline 也没有被遗忘,display: block 变成了 display: block flow——即一个包含在正常流中的子元素的块级元素。display: inline 元素变成了 display: inline flow

display: inline-blockdisplay: 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-blockdisplay: 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 找到她的最新动态。

更多 Rachel Andrew 的文章……