使用 CSS display 的多关键字语法
The CSS display 模块 定义了 CSS display
属性的多关键字语法。本指南解释了多关键字语法。
注意:多关键字语法也称为“双值语法”或“多值语法”。
当我们更改 display 属性的值时会发生什么?
我们学习 CSS 时首先了解到的内容之一是,某些元素是块级元素,而某些元素是内联级元素。这些是它们的 外部 显示类型。例如,<h1>
或 <p>
默认情况下是块级元素,而 <span>
是内联级元素。使用 display
属性,我们可以在块级和内联级之间切换。例如,要使标题成为内联级,我们将使用以下 CSS
h1 {
display: inline;
}
display
属性还允许我们在设置 display: grid
或 display: flex
时使用 CSS 网格布局 和 Flexbox。需要理解的重要概念是,更改元素的 display
值可以更改其直接子元素的格式化上下文。当您使用 display: flex
或 display: grid
时,元素的子元素将成为弹性项目或网格项目,并响应网格和 Flexbox 规范中的属性。
但是,网格和 Flexbox 演示了元素既具有外部显示类型又具有内部显示类型。外部显示类型描述元素是块级还是内联级。内部显示类型描述该框的子元素的行为方式。
例如,当我们使用 display: flex
时,我们创建了一个块级容器,其中包含弹性子元素。子元素被描述为参与弹性格式化上下文。如果您取一个 <span>
(通常是内联级元素)并将其应用于 display: flex
,则可以看到这一点。<span>
将变为块级元素。它在布局中与其他框的关系中表现得像块级元素一样。就好像您已将 display: block
应用于 span 一样,但是我们也获得了子元素行为的改变。
下面的实时示例具有一个应用了 display: flex
的 <span>
。它已成为一个块级框,占据了内联方向上所有可用的空间。您现在可以使用 justify-content: space-between
将此空间放在两个弹性项目之间。
还可以创建内联弹性容器。如果您使用单值 inline-flex
,则将有一个内联级框,其中包含弹性子元素。子元素的行为方式与块级容器的弹性子元素相同。唯一改变的是父元素现在是一个内联级框。因此,它的行为类似于其他内联级元素,并且不占用块级框所占用的全部宽度(或内联尺寸中的大小)。这意味着某些后续文本可能会出现在弹性容器旁边。
在使用网格布局时也是如此。使用 display: grid
将为您提供一个块级框,该框为直接子元素创建网格格式化上下文。使用 display: inline-grid
将创建一个内联级框,该框为子元素创建网格格式化上下文。
使用多关键字语法
从以上说明可以看出,display
属性具有强大的功能。除了指示元素在页面上与其他框的关系中是块级还是内联级外,它还指示应用于它的框内部的格式化上下文。为了更好地描述此行为,display
属性允许在其中设置两个值——外部值和内部值。原始的单值语法也有效。
这意味着,我们不使用 display: flex
来创建具有弹性子元素的块级框,而是使用 display: block flex
。不使用 display: inline-flex
来创建具有弹性子元素的内联级框,而是使用 display: inline flex
。下面的示例演示了这些值。
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: block flow-root 和 display: inline flow-root
关于这种多值语法如何帮助阐明 CSS 布局,我们可以看看上表中一些您可能不太熟悉的 value。多关键字 display: block flow-root
映射到一个单值;display: flow-root
。此 value 的唯一目的是创建一个新的块级格式化上下文 (BFC)。BFC 确保框内的一切都保留在框内,并且框外部的内容无法侵入其中。
在下面的示例中,两个 <p>
元素(一个在 <div>
内部)演示了 display 值如何影响格式化上下文。第一个带有演示控件的 <div>
元素被隐藏,以便我们可以专注于后续的元素。我们应该关注的元素是“父级”、“子级”和“兄弟”<div>
和 <p>
元素,您可以通过它们的 ID 区分它们。
此布局值得注意的一点是,父元素和子元素之间没有内容,并且子元素应用了顶部边距。您可能期望顶部边距有效地将子元素向下推入父元素内,但实际上发生的是称为边距折叠 的情况。在这种情况下,子元素的边距延伸到父元素的边界框之上,并将父元素进一步向下推到页面上。如果您检查子元素的盒模型在浏览器开发者工具中,则更容易看到这一点。
更改 <select>
元素中选定的选项以查看不同 display
值的效果。您可以使用任何带有 flow-root
的值来为父元素创建一个新的格式化上下文,使子元素边距相对于父元素的外边缘,并避免边距折叠。在 display: flow-root
和 display: block flow-root
之间切换将获得与单值 flow-root
关键字相同的效果。
div,
p {
outline: 2px solid black;
background-color: cornflowerblue;
display: block;
margin-bottom: 2rem;
}
#parent {
background-color: oldlace;
min-height: 2rem;
}
#child {
margin-top: 4rem;
outline: 2px dashed red;
}
#sibling {
background-color: lavender;
}
<div id="parent">
<p id="child">The #child paragraph (nested in #parent).</p>
</div>
<p id="sibling">The #sibling paragraph (sibling of #parent).</p>
如果您考虑块级和内联布局(有时称为正常流),则 flow-root
值是有意义的。我们的 HTML 页面创建了一个新的格式化上下文(浮动和边距不能从边界扩展),并且我们的内容以正常流的方式布局,使用块级和内联布局,除非我们将 display
的值更改为使用其他格式化上下文。创建网格或弹性容器也会创建一个新的格式化上下文(分别为网格或弹性格式化上下文)。这些也包含它们内部的所有内容。但是,如果您想包含浮动和边距但继续使用块级和内联布局,您可以创建一个新的流根,并使用块级和内联布局重新开始。从那时起,所有内容都包含在新流根中。
这就是为什么 display: flow-root
可以使用多关键字语法 display: block flow-root
来编写的原因。您正在创建一个块级格式化上下文,其中包含一个块级框,并且子元素参与正常流。匹配对 display: inline flow-root
怎么样?这是描述 display: inline-block
的当前方式。
display: inline-block
值自 CSS 早期就存在。我们倾向于使用它的原因是,例如在创建导航项时,或像下面的示例中那样想要为内联元素添加带有填充的背景时,允许填充将内联项推离元素。
但是,具有 display: inline-block
的元素也将包含浮动。它包含内联级框内的所有内容。因此,display: inline-block
确实与 display: flow-root
执行相同的操作,但使用的是内联级框,而不是块级框。双值语法准确地描述了此 value 发生的情况。在上面的示例中,您可以将 display: inline-block
更改为 display: inline flow-root
并获得相同的结果。
旧的 display 值怎么样?
display
的单值在规范中被描述为旧值,目前您使用多关键字版本不会获得任何好处,因为每个多关键字版本都直接映射到旧版本,如上表所示。
为了处理 display
的单值,规范 解释了如果只使用 block
或 inline
的外部值该怎么办
“如果指定了
<display-outside>
值但省略了<display-inside>
,则元素的内部显示类型默认为 flow。”
这意味着行为与单值世界中的行为完全相同。如果您指定 display: block
或 display: inline
,则会更改框的外部显示值,但任何子元素都将继续以正常流的方式显示。如果只指定了 flex
、grid
或 flow-root
的内部值,则规范 解释说外部值应设置为 block
“如果指定了
<display-inside>
值但省略了<display-outside>
,则元素的外部显示类型默认为 block——除了 ruby,它默认为 inline。”
最后,我们有一些旧的预组合内联级值:
inline-block
inline-table
inline-flex
inline-grid
如果支持的浏览器将这些值作为单值遇到,则将其视为与多关键字版本相同
inline flow-root
inline table
inline flex
inline grid
因此,所有当前情况都得到了很好的涵盖,这意味着我们保持了使用单值的新旧站点的兼容性,同时允许规范发展。