CSS display 属性必知必会

1,690 阅读5分钟

我为什么要为 display 开一篇?

display 属性,对前端同学来说都不会陌生。几年前, “display 的 block、inline、inline-block 有什么区别?” 这道面试题应当是面试必问的了。后来常用的属性又增加了 “flex” 弹性盒子。不管对前端新手还是大神,这个属性都是最为简单、基础、必知必会的了。但我们真的了解这个属性么?

你有没有想过,为什么这个属性是如何定义的呢?为什么 inline-block 又有 block 的特征,又有 inline 的特征呢?

答案都在标准里。

这篇文章就是对标准里 display 属性的详细解读。

display 的含义

display CSS 属性指定了元素的显示类型,它包含两类基础特征,用于指定元素怎样生成盒模型

  • 外部显示类型(outer display type) 定义了元素本身如何参与流式布局的处理
  • 内部显示类型(inner display type) 定义了元素内子元素的布局方式。

关键字取值:

<display-outside>

这些关键字指定了元素的外部显示类型,实际上就是其在流式布局中的角色。我们最熟悉的 block 和 inline 都属于这一类型的关键字.

<display-inside>

这些关键字指定了元素的内部显示类型,它们定义了元素内部内容的格式化上下文的类型(假设是不可替换的元素)。

  • flow

    • 如果其outer display类型是inline或run-in,且其正在参与块或内联格式化上下文,则它会生成inline box;否则会生成一个块容器盒
    • 根据其他属性的值(比如position,float或overflow)以及它本身是否参与块或内联格式化上下文,它要么为其内容建立新的块格式化上下文(BFC),要么将其内容集成到其父格式化上下文
    • (其实就是设置inline和block时默认的)
  • flow-root

    • 该元素生成一个块元素box,用于建立新的块格式化上下文,定义formatting root的所在位置
    • 应用:
      • clearfix
      • 兼容方法:
.wrapper{
   display: flow-root;
}
@supports not (display:flow-root) {
   .wrapper::after {
      content: '';
      display: table;
      clear:both;
   }
}
  • table

    • 行为类似HTML <table>元素。定义了一个block-level box
  • flex

    • 元素行为类似于块元素,并根据 flexbox 模型布置其内容
  • grid

    • 元素行为类似于块元素,并根据 grid model 布置其内容
  • ruby

    • 该元素行为类似于内联元素,并根据ruby格式化模型布置其内容。它的行为类似于相应的HTML元素
    • <ruby>元素被用来展示东亚文字注音或字符注释

<display-listitem>

将这个元素的外部显示类型变为 block 盒,并将内部显示类型变为多个 list-item inline 盒。

list-item 关键字会为元素生成一个 ::marker 伪元素,其内容由 list-style 属性(比如项目符号点)指定

list-item 的单个值会使元素的行为类似于列表项。可以与 list-style-typelist-style-position 一起使用

list-item属性还可以与任何 <display-outside> 关键字以及 flowflow-root 关键字组合使用

Note:

在支持双值语法的浏览器中,如果未指定 inner value,则默认为flow。如果未指定 outer value,则主框具有外部显示的 block

<display-internal>

  • 像 table 和 ruby 这样的布局模型有着复杂的内部结构,因此它们的孩子和后面的元素可能具有多个角色。这一类关键字就是用来定义这些“内部”显示类型,并且只有在这些特定的布局模型中才有意义。
  • 除非另有说明,否则使用这些显示值的元素的内部显示类型和外部显示类型都将设置为给定的关键字。
    • 一堆table-xxx
    • 一堆ruby-xxx

<display-box>

这些值定义元素是否完全生成显示盒。

  • contents

    • 这些元素本身不会生成特定的框。它们被其内容(包括其伪元素和其子元素)取代。  
  • none

    这个大家都很熟了

<display-legacy>

CSS 2 对于 display 属性使用单关键字语法, 对于相同布局模式的 block 级和 inline 级变体需要使用单独的关键字。

大家平时熟悉的 inline-* 都属于这一类型.

  • inline-block

    • 元素会产生一个块元素盒子,并且像内联盒子一样(表现得更像一个被替换的元素),可以融入到周围内容中。
    • 等同于inline flow-root
  • inline-table

    • 在HTML中, inline-table 没有直接对应关系。它表现为一个HTML 元素, 但是又表现为一个不同于块级盒子的内联盒子。表盒子内部是一个块级上下文。
    • 等同于inline table
  • inline-flex

    • 元素表现为一个内联元素,并对内容采用弹性盒子模型进行布局。
    • 等同于inline flex
  • inline-grid

    • 元素表现为一个内联元素,并对内容采用网格模型进行布局。
    • 等同于inline grid

<display-xul> 已废弃 Gecko 62

只有 Firefox 使用,主要用于 XUL 文档 的样式.

总结

双关键字的display虽然被规范定义,但是没有得到浏览器的广泛支持。在更好支持之前,可以使用display-legacy方法来用单个关键字值获得相同结果

Short displayFull displayGenerated box
nonesubtree omitted from box tree
contentselement replaced by contents in box tree
blockblock flowblock-level block container aka block box
flow-rootblock flow-rootblock-level block container that establishes a new block formatting context (BFC)
inlineinline flowinline box
inline-blockinline flow-rootinline-level block container aka inline block
run-inrun-in flowrun-in box (inline box with special box-tree-munging rules)
list-itemblock flow list-itemblock box with additional marker box
inline list-iteminline flow list-iteminline box with additional marker box
flexblock flexblock-level flex container
inline-flexinline flexinline-level flex container
gridblock gridblock-level grid container
inline-gridinline gridinline-level grid container
rubyinline rubyinline-level ruby container
block rubyblock rubyblock box containing ruby container
tableblock tableblock-level table wrapper box containing table grid box
inline-tableinline tableinline-level table wrapper box containing table grid box
typeslayout-specific internal box

参考

developer.mozilla.org/zh-CN/docs/… drafts.csswg.org/css-display…