容器显示类型 ( display )
网页中所有的元素 ( 包含文字 ) 都是一种矩形方框的“容器”,每个容器具有各自的“显示类型”,这些类型会影响容器彼此间的尺寸、位置、对齐等排版显示方式,这篇教学会介绍 CSS display 样式属性,深入理解 inline、block、inline-block、table、grid、flex 这些不同的容器显示类型。
教学影片
搭配教学影片一起阅读,效果会更好!欢迎大家订阅 STEAM 教育学习网的 Youtube 频道。
display 样式属性
display 样式属性可以设定元素的“容器显示类型”,没有继承特性,网页中每个元素都会有自己的 display 属性值,如果属性值改变,该元素的容器类型会发生变化,对应的显示方式也会跟着改变,W3C 将容器显示类型分成六大类:
元素本身 ( display-outside )
HTML 所有元素都会产生容器,这些容器的显示方式分成两大类,主要区分成“内文”和“区块”,其他所有显示类型都会从这两大类进行延伸。
属性值 说明 强制换行 调整宽高 inline 行内容器。 X X block 区块容器。 O O 元素内容特性 ( display-inside )
这个类别的容器属性值是以“区块容器”或“行内容器”为基础,设定后会产生特定的容器特性,这些特性会影响元素里“子元素”的显示方式。
属性值 说明 强制换行 调整宽高 flow 元素流容器。 O O flow-root 元素流根容器。 O O flex 弹性容器。 O O grid 网格容器。 O O table 表格容器。 O O ruby 引用标示容器。 X X 清单项目元素 ( display-listitem )
这个显示类别的属性值主要针对“清单项目”,是清单项目元素的默认值,使用后会将元素转换成 HTML li 元素的显示类型。
属性值 说明 list-item 清单元素容器。 元素内部的子元素结构 ( display-internal )
这个显示类别的属性值主要针对“子元素”,会将子元素的转换成特定元素的显示类型,需要搭配
display:table;或display:ruby;。属性值 说明 table-* 等同 HTML 的 table 相关元素。 ruby-text 等同 HTML rt 元素。 元素显示模式 ( display-box )
设定这个元素是否会产生容器,或这个元素是否会出现。
属性值 说明 contents 不产生容器,呈现子元素容器类型。 none 关闭显示元素的容器,容器从画面中消失不占空间。 特定行为的行内容器 ( display-legacy )
这个显示类别的属性值使用“
inline”开头,会使用行内容器包覆对应的容器,让行内容器同时具有不同特性的区域容器显示方式。属性值 说明 inline-* 行内容器包覆特定容器。
display: inline
inline 属性的元素会产生一个“行内容器”,行内容器具有下列特色:
- 前后没有换行符:如果单行的长度允许,且后方元素不具有换行符,就会将前后元素放在同一行。
- 不能调整宽高:宽高由内容字数的多寡、尺寸自动产生。
通常只要是“文字”或“文字样式”相关的 HTML 元素,都是属性为 inline 的元素,下方范例展示 HTML 默认和设定 display:inline; 的元素会排列在同一行。
<!-- HTML 程式碼 -->
<h1>apple</h1>
<h2>banana</h2>
<span>hello</span>
<em>oxxo</em>
<strong>good</strong>
<sub>morning</sub>
<sup>yes!!</sup>
<a href="google.com">google</a>
<!-- CSS 程式碼 -->
<style>
h1, h2 {display: inline;} /* 這些元素預設為 display: block; */
</style>
display: block
block 属性的元素会产生一个“区块容器”,区块容器具有下列特色:
- 前后有换行符:出现区块容器会强制换行。
- 可以设定宽高:使用长度单位数值设定宽高尺寸。
通常只要是“div、p 或 h1~h6”相关的 HTML 元素,都是属性为 block 的元素,下方范例展示 HTML 默认和设定 display:block; 的元素会换行并垂直排列。
<!-- HTML 程式碼 -->
<h2>apple</h2>
<h3>banana</h3>
<span>hello</span>
<em>oxxo</em>
<strong>good</strong>
<a href="google.com">google</a>
<!-- CSS 程式碼 -->
<style>
span, em, strong, a {display: block;} /* 這些元素預設 display: inline; */
</style>
display: flow
flow 属性的元素会变成“呈现元素流方向的容器”,由于这个样式属性不是标准属性值,平常不会去使用它 ( 属于元素内部显示类型,表示该元素位于元素流里面 ),使用后会返回 block 属性值,因此产生的效果和区块容器相同,也都会强制换行,下方范例将 span 元素设定为 display: flow;。
<!-- HTML 程式碼 -->
<strong>oxxo</strong>
<span>apple</span>
<em>banana</em>
<!-- CSS 程式碼 -->
<style>
span {display: flow;}
</style>
display: flow-root
flow-root 属性的元素会变成“元素流的根容器”,表示该容器会“独立为子元素元素流的根元素”,子元素的排版会自己独立,不会去影响到别的容器,这种情形特别常见于 float 浮动排版,因为浮动元素会脱离原本的平面,但由于仍然在元素流里,所以同一个元素流中的元素仍然会互相干扰,但如果父元素设定为 flow-root,则元素流互相独立,一些会互相干扰的排版也就不会系互相影响 ( 有时可作为解除浮动效果使用 )。
元素设定为 flow-root 后会强制换行,下方范例将 class 为 a 的 div 元素设定为 display: flow-root;,可以看见虽然子元素设定了 float: left;,却不会影响到下层的 div,而 class 为 b 的 div 因为采用默认显示类型,两个 div 的会互相干扰。
<!-- HTML 程式碼 -->
<div class="a">
<strong>apple</strong>
<em>banana</em>
<span>oxxo</span>
</div>
<div class="a">
<strong>apple</strong>
<em>banana</em>
<span>oxxo</span>
</div>
<div class="b">
<strong>apple</strong>
<em>banana</em>
<span>oxxo</span>
</div>
<div class="b">
<strong>apple</strong>
<em>banana</em>
<span>oxxo</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
margin : 10px;
border: 1px solid #000;
}
div * {float: left;} /* div 子元素浮動靠左 */
.a {display: flow-root;} /* 設定為這個元素流的根容器 */
</style>
display: flex
flex 属性的元素会变成“弹性容器”,弹性容器具有下列特色:
- 使用 block 显示方式:前后具有换行符,会强制换行。
- 子元素变成弹性项目:搭配其他 flex 相关样式,实作子元素的网格排版。
- 详细参考:认识弹性盒子 Flexbox。
HTML 里没有默认 display: flex; 的元素,但越来越多网页因为排版的需求,会将元素修改为 flex 属性,下方范例展示 HTML 有设定 display:flex; 和没有设定的 div 与其子元素的差异。
<!-- HTML 程式碼 -->
<div class="a">
<span>oxxo</span>
<em>apple</em>
<strong>banana</strong>
<a href="google.com">google</a>
</div>
<div class="b">
<span>oxxo</span>
<em>apple</em>
<strong>banana</strong>
<a href="google.com">google</a>
</div>
<!-- CSS 程式碼 -->
<style>
div {
width: 300px;
border: 1px solid #000;
margin: 10px;
}
.a {
display: flex; /* 彈性容器內容的空白會消失 */
}
</style>
display: grid
grid 属性的元素会变成“网格容器”,网格容器具有下列特色:
- 使用 block 显示方式:前后具有换行符,会强制换行。
- 子元素变成网格项目:搭配其他 grid 样式,实作子元素的网格排版。
- 详细参考:使用 Grid 网格容器与格线。
HTML 没有默认 display: grid 的元素,但越来越多网页因为排版的需求,会将元素修改为 grid 属性,下方范例展示 HTML 有设定 display:grid; 和没有设定的 div 与其子元素的差异。
<!-- HTML 程式碼 -->
<div class="a">
<span>oxxo</span>
<em>apple</em>
<strong>banana</strong>
<a href="google.com">google</a>
</div>
<div class="b">
<span>oxxo</span>
<em>apple</em>
<strong>banana</strong>
<a href="google.com">google</a>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
margin: 10px;
}
.a {
display: grid;
grid-template-rows: 20px; /* 每一列高 20px */
grid-template-columns: repeat(2, 100px); /* 每列兩欄,每欄 100px */
}
</style>
display: table
table 属性的元素会变成“表格容器”,表格容器具有下列特色:
- 使用 block 显示方式:前后具有换行符,会强制换行。
- 使用内容宽度:透过内容撑开宽度。
- 子元素变成表格项目:搭配其他
table-*属性值,实作子元素的表格排版。- 详细参考:认识表格、表格默认样式。
下方范例会将所有 div 里头的 span 转换成类似表格 tr 的显示方式,em 转换成表格 td 的显示方式,可以看出 class 为 a 的 div 会呈现出类似表格的长相,而另外的 div 只有内容类似表格,但外部仍保留 div 原本的显示类型。
<!-- HTML 程式碼 -->
<div class="a">
<span>
<em>apple</em><em>banana</em>
</span>
<span>
<em>oxxo</em><em>coconut</em>
</span>
</div>
<div class="b">
<span>
<em>apple</em><em>banana</em>
</span>
<span>
<em>oxxo</em><em>coconut</em>
</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
margin: 10px;
}
.a {
display: table;
}
div span {
display: table-row; /* 等同 tr */
}
div em {
display: table-cell; /* 等同 td */
}
</style>
display: ruby
table 属性的元素会变成“引用标示容器”( 参考“标示注音”),引用标示容器具有下列特色:
- 使用 inline 显示方式:前后没有换行符,不会强制换行。
- 不能调整宽高:因为是 inline 的显示类型,不能调整宽高。
- 子元素需要手动设定
ruby-text属性值,才能让子元素变成标示项目,标示特定消息。
HTML 的 ruby 元素通常作为“标示注音或发音”使用,下方范例会将 class 为 a 的 div 设定 display: ruby;,里头的 span 设定为 display: ruby-text; ( 等同 rt 元素 ),就能做出上下标著的效果,而另外一个 div 则是采用默认的样式作为对照组。
<!-- HTML 程式碼 -->
<div class="a">
oxxo<span>apple</span>
oxxo<span>banana</span>
oxxo<span>orange</span>
</div>
<div class="a">
oxxo<span>apple</span>
oxxo<span>banana</span>
oxxo<span>orange</span>
</div>
<div>
oxxo<span>apple</span>
oxxo<span>banana</span>
oxxo<span>orange</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
margin: 10px;
height: 100px;
border: 1px solid #000;
}
.a {
display: ruby;
}
.a span {
display: ruby-text; /* 註解標示的文字 */
padding: 0 2px;
}
</style>
display: list-item
list-item 属性的元素会变成“清单项目容器”,清单项目容器具有下列特色:
- 类似区块元素:前后具有换行符,会强制换行。
- 必须要放在区块元素里:需要包覆一个区块元素,不然就没有作用。
- 产生一个
::marker虚拟元素:这个虚拟元素负责清单符号样式,可透过清单样式设定。- 详细参考:清单样式 list-style。
HTML 的“li”元素是默认 display: list-item 的元素,下方范例会将 class 为 a 的 div 里头的元素转换成 display: list-item,可以观察出有设定和没有设定的差异。
<!-- HTML 程式碼 -->
<div class="a">
<strong>apple</strong>
<em>banana</em>
<span>oxxo</span>
</div>
<div class="b">
<strong>apple</strong>
<em>banana</em>
<span>oxxo</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
margin : 10px;
border: 1px solid #000;
}
.a * {
display: list-item;
margin-left: 30px;
}
.a *::marker {
content: ">> ";
}
</style>
display: table-*
table-* 属性的元素会变成“表格容器的子元素”,使用时会将元素转换成对应的表格元素显示类型,下方是对照表:
| 属性值 | 对照元素 |
|---|---|
| table-row | tr |
| table-cell | td |
| table-caption | caption |
| table-header-group | thead |
| table-row-group | tbody |
| table-footer-group | tfoot |
| table-column | col |
| table-column-group | colgroup |
下方范例会将 class 为 a 的 div 设定为 display: table;,接着把内容子元素设定成表格的子元素显示类型,呈现和 div 的默认值截然不同的感觉。
- 详细参考:认识表格、表格默认样式。
- 线上展示:https://codepen.io/oxxo/pen/MWdVvzw
<!-- HTML 程式碼 -->
<div class="a">
<span>
<em>apple</em><em>banana</em><em>orange</em>
</span>
<span>
<em>apple</em><em>banana</em><em>orange</em>
</span>
</div>
<div>
<span>
<em>apple</em><em>banana</em> <em>orange</em>
</span>
<span>
<em>apple</em><em>banana</em><em>orange</em>
</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
margin: 10px;
}
.a {
display: table;
border-collapse: collapse; /* 表格邊緣合併 */
}
.a span {
display: table-row; /* 等同 tr */
border: 1px solid #000;
}
.a em {
display: table-cell; /* 等同 td */
border: 1px solid #000;
padding: 10px;
}
</style>
display: ruby-text
ruby-text 属性的元素会变成“标记容器的子元素”,使用时会将元素转换成对应 HTML 的 rt 元素显示类型,下方范例会将 class 为 a 的 div 设定 display: ruby;,里头的 span 设定为 display: ruby-text; ( 等同 rt 元素 ),就能做出上下标著的效果,而另外一个 div 则是采用默认的样式作为对照组。
<!-- HTML 程式碼 -->
<div class="a">
oxxo<span>apple</span>
oxxo<span>banana</span>
oxxo<span>orange</span>
</div>
<div class="a">
oxxo<span>apple</span>
oxxo<span>banana</span>
oxxo<span>orange</span>
</div>
<div>
oxxo<span>apple</span>
oxxo<span>banana</span>
oxxo<span>orange</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
margin: 10px;
height: 100px;
border: 1px solid #000;
}
.a {
display: ruby;
}
.a span {
display: ruby-text;
padding: 0 2px;
}
</style>
display: contents
contents 属性的元素“不会产生容器”,HTML 没有默认 display: contents; 的元素,这个属性值具有下列的特色:
- 直接让子元素呈现自己的
display属性。
下方范例将一些元素设定为 display: contents;,可以看出当 div 设定为 contents,里头的 span 仍然会保有 inline 的行内容器特性,并不会因为外围是 div 就强制换行。
<!-- HTML 程式碼 -->
<div>
<span>hello</span>
</div>
<span>oxxo</span>
<div>
<em>good</em>
</div>
<strong>morning</strong>
<a href="google.com">google</a>
<!-- CSS 程式碼 -->
<style>
div {display: contents;}
</style>
display: none
none 属性的元素“关闭显示元素的容器”,这个属性值具有下列的特色:
- 影响子元素:设定
display: none;的元素与子元素会一起被关闭显示。- 容器消失不占空间:由于容器已经被关闭,因此会从画面中消失,且不占任何空间。
下方范例将一些元素设定为 display: none;,可以看出这些元素就从画面中消失,因为不占空间,后方的元素就会替补上来 ( class 为 a 的 div,因为 h3 被设定关闭显示,所以强制换行效果就消失了 )。
<!-- HTML 程式碼 -->
<div class="a">
<span>apple</span>
<h3>oxxo</h3>
<span>banana</span>
</div>
<div>
<span>apple</span>
<h3>oxxo</h3>
<span>banana</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
margin: 10px;
}
.a h3 {display: none;} /* 關閉顯示這個元素 */
</style>
display: inline-*
inline-* 属性的元素表示“特定行为的行内容器”,使用时会使用行内容器包覆的特定容器,下方是对照表:
| 属性值 | 说明 | 调整宽高 | 垂直对齐 | 水平对齐 | 强制换行 |
|---|---|---|---|---|---|
| inline-block | 行内容器包覆区块容器。 | O | O | O | X |
| inline-flex | 行内容器包覆弹性容器。 | O | O | O | X |
| inline-grid | 行内容器包覆网格容器。 | O | O | O | X |
| inline-table | 行内容器包覆表格容器。 | O | O | O | X |
因为外部是行内容器,所以可以使用 text-align 或 vertical-align 的方式进行水平或垂直对齐,而又因为内部包裹了区块容器特性的容器,因此也可以调整宽高或采用对应的行为,下方范例列出四种不同特定行为的行内容器。
<!-- HTML 程式碼 -->
<div class="a">
<span>aabb</span>
<h3>oxxo</h3>
<em>ccdd</em>
<strong>ggyy</strong>
</div>
<div class="b">
<span>aabb</span>
<h3>oxxo</h3>
<em>ccdd</em>
<strong>ggyy</strong>
</div>
<div class="c">
<span>aabb</span>
<h3>oxxo</h3>
<em>ccdd</em>
<strong>ggyy</strong>
</div>
<div class="d">
<i>
<span>aabb</span>
<h3>oxxo</h3>
</i>
<i>
<em>ccdd</em>
<strong>ggyy</strong>
</i>
</div>
<!-- CSS 程式碼 -->
<style>
h3 {margin: 0;}
div {
border: 1px solid #000;
vertical-align: bottom; /* 垂直對齊底部 */
}
.a { display: inline-block;}
.b { display: inline-flex;}
.c {
display: inline-grid;
grid-template-rows: 30px; /* 設定網格每一列高度 */
grid-template-columns: repeat(2,60px); /* 設定網格重複樣式 */
}
.d {display: inline-table;}
.d i {display: table-row;} /* tr 容器型態 */
.d i * {display: table-cell;} /* td 容器型態 */
</style>
小结
display 是一个很常与“排版”有关的样式属性,透过改变元素的容器显示类型,就能让相同的元素适应不同的版面需求,甚至还会影响各种对齐与尺寸的设定,透过这篇教学的介绍,相信对于 display 能有更深的认识。
微信扫码关注
抖音扫码关注