桔梗

display:contents 与消失的盒模型

桔梗 · 2016-11-20翻译 · 768阅读 原文链接

在CSS3可视化模块中,display: contents是display属性一个新的属性值。FireFox已经实现了对该属性的支持,这里将简单介绍该属性的作用,及其被浏览器广泛支持后存在实用价值的原因。

【规范】(https://drafts.csswg.org/css-display/#box-generation)

"元素本身不能生成任何盒模型,但是它的子元素或者伪元素可以正常生成。为了盒模型的生成与布局,该元素就好像在Dom树中被子元素与伪元素所替代一样“

上述规范说明了我们可以在文档中添加一个HTML元素,并在该元素的选择器中添加display:contents样式,那么该元素就会像是不存在一样,它的子元素会替代它在Dom树中的位置。

使用示例理解起来更加容易,因此我们需要使用FireFox.

假设现在我们有两个Div元素,外层的Div元素拥有类content,内层Div元素拥有类inner。分别为它们添加背景色与边界,如下所示:

simple example of display contents

如果为外层Div元素添加display:contents属性,示例变为

after applying display contents

外层Div消失了,我们看不到外层Div的背景,边框 ,甚至应用到该元素的宽度也已经失效了,内层Div元素则占据了整个视口。display:contents便是这样起作用的。可以使用FireFox打开CodePen中的该示例查看效果。在不支持该属性的浏览器中,display:contents将会被忽略。

需要注意的是,内部Div元素不能继承的属性仅仅是那些与盒模型生成或布局相关的。我们可以在外层Div元素上设置font-size属性,其子元素则会继承该属性。

示例链接 display: contents by rachelandrew (@rachelandrew) on CodePen.

使用 display:contents 来实现Flex项目的“继承”

这可能有用吗?如果你正在使用弹性布局,那么你应该知道只有Flex容器的直接子元素可以成为Flex项目。而Flex项目的子元素是不能够使用父元素的规则来进行布局的。

我们可以通过一个简单的示例来印证。有一个Div包含快,内部直接嵌套了三个类名分别为box1、box2、box3的Div元素,这三个Div均是Flex项目,可以对它们使用弹性布局。然而box4、box5是box2元素的子元素,因此尽管我们已经应用Flex项目属性到box5,但由于其父元素display属性没有被设置为flex,因此会被忽略。

我们给第二个Flex项目添加一个明显的背景和边界来帮助我们看清楚发生了什么。

Flex items before using display contents

如果为box2添加属性displsy:content,则在FireFox中我们将看到box2已经消失了,我们也不能看到橘色的边界和背景。不仅仅是这样,它好像已经在Dom树中完全消失不见了。而box2的子元素则像Flex项目一样,应用到box5上面的样式也生效了。

Flex items after using display contents

这是站点CodePen上的一个示例。

查看 display: contents and flexbox by rachelandrew (@rachelandrew) on CodePen.

非常感谢Jake Archibald允许我使用他的demo进行介绍。

如果想添加一些有语义但又不显示的元素,那么该属性是非常有用的。如果有一些内容在语义上适合被标记为article,然而article元素在布局上是Flex项目,但是你真正希望的是使article内部嵌套的元素作为Flex项目存在。那么为了使article嵌套的元素成为Flex项目,比起去除article元素,你更应该使用display:contents来移除article产生的盒模型。这样做你将会在语义化以及显示效果上都能得到很好地效果。听起来还不错。

相关文章