如何理解 CSS 中的 display 属性
display 是 CSS 控制布局最核心的属性。每一个 HTML 元素都拥有默认的 display 值,由元素本身语义决定,绝大多数元素默认值为 block 或者 inline。
display 同时控制元素外部显示类型与内部显示类型:
- 外部显示类型:决定元素在普通流式布局下的表现,区分块级、内联行为;
- 内部显示类型:决定它的子元素该如何布局,支持普通流、table、flex、grid 等多种上下文。
display 属性总览
| 规范版本 | 属性值 |
|---|---|
| CSS1 | none、block、inline、list-item |
| CSS2.1 | inline-block、table、inline-table、table-* 系列 |
| CSS3 | flex、inline-flex、grid、inline-grid、flow-root、ruby、contents、inline-list-item(兼容性差)等 |
注意:CSS3 引入了双值语法,例如 display: block flex,外部值写在前,内部值写在后,现代浏览器支持。
常用属性详解
display: none
元素完全从渲染树移除,不占据页面任何空间,视觉上完全消失。
<script>、<style> 这类标签默认就是 display: none。
和 visibility: hidden 的区别:
display: none:元素不渲染,不占位;visibility: hidden:元素依然渲染,保留原有空间,仅仅看不见。
display: block —— 块级盒子
block 即块级元素,会独占一行,表现为块级盒子。display: block 不会单独创建 BFC。
核心特性
- 独占一行,前后自动换行;
- 可以设置
width、height; - 默认宽度:父容器 100%;默认高度:由内容自适应;
margin、padding四个方向全部生效。
常见块级元素:div、h1~h6、p、hr、form、ul、ol、dl、fieldset、blockquote、pre。
display: inline —— 行内(内联)盒子
inline 行内元素,多个行内元素可以排在同一行。
核心特性
- 和其他行内元素横向排在同一行;
- 宽高无法手动设置,宽高完全由内容(文字、图片)决定;
- 垂直方向的
margin-top、margin-bottom无效;padding-top、padding-bottom背景会渲染,但不会推开周围文档流; text-align作用于父元素,用来控制子行内元素对齐;line-height会影响行内盒子垂直位置。
常见行内元素:span、a、label、em、strong、code、b、i、abbr、q、sub、sup。
注意:<img> 属于替换行内元素,行为有部分特殊,可以设置宽高。
inline 元素之间空白间隙问题:多个行内元素,源码里的换行、空格,浏览器会解析成肉眼可见的空白间隔。
<section>
<img src="a.jpg">
<img src="b.jpg">
</section>
空白间隙解决方案:
源码去掉换行与空格,标签紧贴书写:
<img src="a.jpg"><img src="b.jpg">。改为
inline-block配合消除间隙方案;- 父容器设置
font-size: 0;,子元素重新恢复字号。
display: list-item
让普通元素表现为列表项,浏览器自动生成项目符号。
可以配合 list-style-type、list-style-position 控制标记样式。
备注:inline-list-item 为 CSS3 新增,主流浏览器兼容性很差,几乎不可用。

<style>
.list-item span {
display: list-item;
list-style-position: inside;
list-style-type: cambodian;
}
</style>
<section class="list-item">
<span>世上最凄绝的距离是两个人本来距离很远,互不相识,</span>
<span>忽然有一天,他们相识,相爱,距离变得很近。</span>
<span>然后有一天,不再相爱了,本来很近的两个人,变得很远,甚至比以前更远。</span>
</section>
display: inline-block —— 行内块
inline-block 结合了行内与块级两者的特点:盒子本身是块盒,可以设置宽高;外部表现为行内,可以和其他元素排在同一行。
特性
- 可设置
width、height; - 多个元素横向同行排列;
- 默认宽高由内容自适应;
margin、padding全部方向生效。
原生默认 inline-block 的元素:input、textarea、select、button。
注意:同样会受源码空白符影响,产生元素间的小间隙。
display: table 系列
把普通 div 模拟成 HTML table 的一套结构,对应原生表格标签。
| display 值 | 对应原生标签 | 说明 |
|---|---|---|
table |
<table> |
块级表格,前后换行 |
inline-table |
— | 行内表格,和其他内容同行 |
table-row |
<tr> |
表格行 |
table-cell |
<td>、<th> |
单元格 |
table-row-group |
<tbody> |
行分组 |
table-header-group |
<thead> |
表头分组 |
table-footer-group |
<tfoot> |
表尾分组 |
table-column |
<col> |
列定义 |
table-column-group |
<colgroup> |
列分组 |
table-caption |
<caption> |
表格标题 |
table-cell 拥有表格单元格的固有行为,是过去非常经典的布局手段:
- 单元格垂直居中:利用
vertical-align: middle实现内部内容垂直居中。 - 两栏自适应布局:一侧浮动固定,另一侧设置
table-cell,自动占满剩余宽度。 - 多栏等高布局:同一行内所有
table-cell单元格高度自动保持一致。
display: flex、inline-flex —— 弹性盒
flex:块级弹性容器;inline-flex:行内弹性容器。
备注:设置 flex 容器之后,子元素的 float、clear、vertical-align 全部失效。
注意:display: box 是老旧的 flexbox 草案版本,属于过时非标准写法,仅用于兼容非常老旧移动端,新项目禁止使用。
display: grid、inline-grid —— 网格布局
grid 是二维网格布局,可以同时控制行与列;inline-grid 为行内网格。
通过定义行轨道、列轨道,实现复杂二维排版,引入了 fr 分数单位。
display: flow-root
flow-root 生成一个块盒,自动创建 BFC(块级格式化上下文),没有其他副作用。
BFC 典型用途:
- 清除内部子元素浮动带来的高度塌陷;
- 阻止父子外边距折叠。
对比其他创建 BFC 方式:
overflow: hidden:会裁剪溢出内容,有副作用;float、position: absolute:会改变元素本身布局行为;display: flow-root:只创建 BFC,不做额外改动,是理想方案。
display: ruby 系列
ruby 用来实现注音旁注(类似汉字拼音标注),配套还有 ruby-base、ruby-text。
目前各浏览器对 CSS display: ruby 的支持不一致,注音旁注优先用原生 <ruby> 标签,业务项目谨慎使用 display: ruby。
<style>
.ruby-wrap {
display: ruby;
font-size: 26px;
line-height: 2.5;
}
.ruby-base {
display: ruby-base;
}
.ruby-text {
display: ruby-text;
font-size: 14px;
color:#666;
}
</style>
<div class="ruby-wrap">
<span class="ruby-base">叶</span><span class="ruby-text">yè</span>
<span class="ruby-base">青</span><span class="ruby-text">qīng</span>
<span class="ruby-base">苔</span><span class="ruby-text">tái</span>
<span class="ruby-base">归</span><span class="ruby-text">guī</span>
<span class="ruby-base">路</span><span class="ruby-text">lù</span>
<span class="ruby-base">,</span>
<span class="ruby-base">屧</span><span class="ruby-text">xiè</span>
<span class="ruby-base">粉</span><span class="ruby-text">fěn</span>
<span class="ruby-base">衣</span><span class="ruby-text">yī</span>
<span class="ruby-base">香</span><span class="ruby-text">xiāng</span>
<span class="ruby-base">何</span><span class="ruby-text">hé</span>
<span class="ruby-base">处</span><span class="ruby-text">chù</span>
</div>
HTML 原生自带 <ruby> 标签,优先用原生标签,CSS display: ruby 是 CSS 方式模拟:

<ruby style="font-size:26px; line-height:2.5;">
叶<rt>yè</rt>
青<rt>qīng</rt>
苔<rt>tái</rt>
归<rt>guī</rt>
路<rt>lù</rt>
,<rt></rt>
屧<rt>xiè</rt>
粉<rt>fěn</rt>
衣<rt>yī</rt>
香<rt>xiāng</rt>
何<rt>hé</rt>
处<rt>chù</rt>
</ruby>
display: contents
contents 会让当前元素盒子消失,它的子元素直接提升到上一级参与布局。
仅仅移除浏览器渲染层面的盒子,内存中的 DOM 对象依然完整保留:
- 元素本身所有 CSS 样式全部失效;
- 可继承属性依旧会继承给子元素;
- JS 绑定的事件监听器依旧挂载在该 DOM 节点上。
拓展概念
什么是块级元素?
不止 display: block 才叫块级元素。
属于块级盒子:
display值:block、list-item、table、flex、grid;- 元素设置
float: left、right; - 元素设置
position: absolute、fixed。
备注:当元素被浮动或者绝对定位时,不管原来 display 是什么,会自动转换为块盒。
内联盒模型核心概念
来自 CSS 内联格式化上下文规范,理解 line-height、vertical-align 的基础。
- 内容区域 content-area:看不见的虚拟盒子,大小由字体度量(font-metrics:ascender、descender)、
font-size、font-family共同决定,和line-height无关。不同字体,同样字号,内容区域可能高度不一样。 - 内联盒子 inline-boxes:每一个行内标签、裸文本都会生成一个内联盒子。裸文本生成匿名内联盒子。
- 行框盒子 line-boxes:每一行就是一个行框盒子,由本行所有内联盒子组合而成。行框盒子高度由本行最高的虚拟高度决定。
- 包含盒子 containing box:容器盒子,由多行行框盒子堆叠而成,整体高度等于各行行框盒子高度累加。
为什么不建议行内元素里面嵌套块元素?
HTML 规范不允许行内元素内部直接放置块级元素,浏览器会做自动修复,产生意料之外的 DOM 渲染结果。
示例:span 表示想要一行显示,遇到块元素会自动换行,这不符合我们对行内元素的第一感知(行内元素是在一行显示的)。

<section>
<span>
黄叶青苔归路,屧粉衣香何处。消息竟沉沉,今夜相思几许。
<img
style="display: block; width: 50px;"
src="https://my-files-1259410276.cos.ap-chengdu.myqcloud.com/md_images/落了白.png"
>
秋雨,秋雨,一半因风吹去。—纳兰性德-如梦令
</span>
</section>
注意:此时 JS 获取 span 的 clientHeight 会得到 0,会造成 JS 获取尺寸异常。