热门搜索 :
考研考公
您的当前位置:首页正文

前端开发入门 :理解`display`

来源:东饰资讯网

# 元素的显示类型 在学习CSS盒模型的时候,我们还简单地提及了“块”和“行”这一概念。 “块”或者“行”,决定一个元素的显示类型,而元素的显示类型又会影响元素盒模型的表现。 为了方便大家梳理知识,这里我举一个可能不是非常恰当的例子,你可以这样理解:控制元素的盒模型,就好像是给一个人化妆,可以化出非常多的花样;而元素的显示类型,像是一个人的生理性别,是更根本的东西,性别会影响一个人的妆容。必要的时候,我们可以借助医学手段来改变性别。 在CSS中,我们通过设置元素的`display`属性来改变元素的显示类型,例如以下这行代码:

``` span {  display: block; } ```

它的意思是,把页面中所有`span`元素显示为“块”。 如果我们没有显性地为元素设置`display`属性,那么元素的显示类型是由浏览器的默认样式表决定的。例如span,默认情况下它的`display`的值是`inline`,是一个行元素。 对于绝大多数元素(html标签),我们并不需要特别去记忆它们的默认显示类型。这一方面是因为,根据元素标签的语义,我们常常能直觉出元素是“块”还是“行”;另一方面是因为,元素到底是“块”还是“行”,在视觉上是显而易见的,只要用到了马上就能看出来。 我们把一个文档的内容排列称为一个“文档流”(flow)。在这个文档流里,“块”元素会引发断行,在不受干扰时,它总是自占一行;“行”元素不会。

# `display`的外显与内在 `display`乍看上去是一个比较简单的属性,它的使用频率比较高,并且常见的取值只有三两个。大多数前端开发人员可能都没有想过这里边有什么不得而解的复杂。 但事实上,很少人真正明白`display`的意味。许多布局上错综复杂的东西,如果正确地理解了`display`,就能够迎来柳暗花明。 就我个人,也并非完全理解`display`的方方面面。但我会尽可能在我的认知范围里,用一种合适初学者的方式,向你讲清楚这件事。它不是什么特别艰巨的难题,但如果现在不讲清楚、不对它形成一个正确的印象,可能以后你都不会搞清楚它了。你会变得像其它前端开发人员一样,靠一种懒惰的“直觉”来使用它,“直觉”对的时候没什么问题,遇到“直觉”解决不了的,就去抄一些对自己而言像天书的解决方法。 应该说,`display`实际上决定了一个元素的两个方面。 首先,它决定了我们前文已经阐述过的,元素的显示类型。确切地说,是元素的外部显示类型(outer display type)。它说的是这样一件事:一个元素对于它身处的这个外部文档流而言,是一个什么东西,是一个“块”呢,还是一个“行”。 相应地,它还决定了一个元素的内部显示类型(inner display type)。这个内部显示类型,为该元素的子元素提供了一个“格式上下文”(formatting context),不同的格式上下文,会对子元素的布局表现产生不同的影响。

# 元素的外部显示类型 我们先来看前者。 相对来说,外部显示类型是比较简单的。它只有三种可能:

* block

* inline

* run-in

其中`run-in`这个类型目前几乎没什么浏览器支持,实践上用不到,所以实际上只剩下两个类型。 这两个类型就是我们一直在说的“块”和“行”。 没了。挺简单的,对吧?

# 元素的内部显示类型 内部显示类型要微妙一些。 这里头的复杂,其实是因为,现行的CSS规范里,`display`的值是一个单一的关键字,这个关键字同时决定了元素的外部与内部显示类型。而多数情况下,这个关键字的字面,要么只描述了外部类型,内部类型是隐含的;要么只描述了内部类型,外部类型是隐含的。 比方说,当我们写上`display: block`这句代码时,我们的意思其实是:把这个元素的外部显示类型设置为`block`,而把它的内部显示类型设置为`flow`。 以后的CSS规范,有可能会允许我们完整地写上全部两个关键字。到时候由这引起的混淆将会消失。在那之前,你可能需要先让你的脑子转动一下,自行解决一下这种混淆。

明白了复杂的由来后,我们来具体说一说元素的内部显示类型。它主要有这么一些取值:

* flow

* flow-root

* table * ruby

* flex

* grid

* subgrid

首先,作为初学者,你可以先排除掉`table`和`ruby`这两个值。这两个值是和html中的`<table>`以及`<ruby>`这两个标签配套的。 `

<table>`和`<ruby>`元素在布局上都有它们的特殊性,所以有单独的内部显示类型,你需要理解这些内部显示类型。但你绝绝大多数时候不会做的是,通过设置`display`来把其它元素的类型设置为`table`和`ruby`。一般我们没有这种需求,如果我们需要那种布局方式,我们会直接在html里使用`<table>`和`<ruby>`标签。 因此,你可以在深入学习`<table>`和`<ruby>`的同时,再去理解这两种内部显示类型。而在我们讨论通用的`display`属性时,你暂且可以认为`table`和`ruby`这两个取值是不存在的,这能让我们学期起来轻松一点。

其次,`grid`和`subgrid`这两个值用在一种目前来说还非常新的布局方式里。大多数人都还不会用,实践上也还受到浏览器兼容性的钳制,所以你也可以先不理会它们。

于是最后我们就只剩下`flow`、`flow-root`和`flex`这三种取值了。

当我们给元素设置`display: block`或`display: inline`时,会暗含该元素的内部显示类型是`flow`。就好像你写的其实是`display: block flow`以及`display: inline flow`。 目前的通行的CSS规范里,`flow`和`flow-root`这两种内部显示类型总是暗含的,你从来不会直接地使用到这两个关键字。 `

flow`可以简单地理解为“默认的、常态的格式上下文”,它是最常见的但同时也是最难理清的一种内部显示类型。对于`display: inline`的元素而言,它只是一个简单的行框,表现出来的就是我们上一篇提到的,设置不了宽高等等。而对于`display: block`的元素而言,在不同的场合下,它会有不同的表现。 至于`flow-root`,它根本上是“块”元素的`flow`的“不同的表现”里的其中一种可能性(生成“块级格式上下文”),是一种更可控的`flow`。

如果你看不太懂,没关系,大多数前端开发人员和你一样不懂,你先有这个印象,就已经在这方面强于他们了。 而`display: flex`,它实际上是`display: block flex`。把元素内部显示类型设置为`flex`,并暗含它的外部显示类型是`block`。 以后我们将会具体地学习`flex`,它是一个非常有用的内部显示类型。

# `inline-block`、`inline-flex`和`inline-table` 我们前面说到,`display`的值具有一种“暗含”性质。但总是隐忍着不说出来,有些事就会搞不清楚。 比如说,在当前这个规范下,当我想要一个外部是`inline`、内部是`flex`的元素怎么办?为了解决这种问题,就出现了一批`inline-*`取值。

`display: inline-block`相当于`display: inline flow-root`。

`display: inline-flex`相当于`display: inline flex`。

`display: inline-table`相当于`display: inline table`。

其中`display: inline-block`特别常见。它的意思是,让这个元素对外部而言是个“行”元素(不会产生断行),但同时让它的内部表现得像是具有“块级格式上下文”的`display: block`那样(这时候可以设置宽高了)。

# 隐藏元素 `display: none`可以让一个元素从文档流中彻底消失。

# 总结 根本上,你现在最可能用到的`display`声明是以下这几种:

* `display: block`(相当于`display: block flow`)

* `display: inline`(相当于`display: inline flow`)

* `display: inline-block`(相当于`display: inline flow-root`)

* `display: flex`(相当于`display: block flex`)

* `display: inline-flex`(相当于`display: inline flex`)

* `display: none`

你应该先练习`block`、`inline`、`inline-block`以及`none`这四种取值,写写代码、在浏览器里试试它们的表现差异。 于此同时,在你的目前的认知范围里,尽可能理解我们上文解释的一系列概念。我明白这有些复杂、过于抽象,但它们非常重要,并且可能是你在别的地方很难学到、甚至很难意识到的。随着学习的进行,这些概念会越来越清晰。并且你可以相信我,如果你正确地理解了这些概念,你的CSS布局水平至少好于市面上80%的前端开发人员。

* 目前已经开始有浏览器准备支持`display: flow-root`,它相当于`display: block flow-root`,总是会在内部生成一个“块级格式上下文”,比`display: block flow`更可控,通常是我们更想得到的结果。

Top