容器顯示類型 ( display )
網頁中所有的元素 ( 包含文字 ) 都是一種矩形方框的「容器」,每個容器具有各自的「顯示類型」,這些類型會影響容器彼此間的尺寸、位置、對齊等排版顯示方式,這篇教學會介紹 CSS display 樣式屬性,深入理解 inline、block、inline-block、table、grid、flex 這些不同的容器顯示類型。
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
屬性的元素會變成「呈現元素流方向的容器」,基本上使用這個容器的效果和區塊容器相同,都會強制換行,下方範例將 span 元素設定為 display: flow;
。
<!-- HTML 程式碼 -->
<strong>oxxo</strong>
<span>apple</span>
<em>banana</em>
<!-- CSS 程式碼 -->
<style>
span {display: flow;}
</style>
display: 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 相關樣式,實作子元素的網格排版。
HTML 裡沒有預設 display: flex;
的元素,但越來越多網頁因為排版的需求,會將元素修改為 flex
屬性,下方範例展示 HTML 有設定 display:flex;
和沒有設定的 div 與其子元素的差異 ( 詳細的 flex 會在 Flexbox 排版的教學裡介紹 )。
<!-- 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 樣式,實作子元素的網格排版。
HTML 沒有預設 display: grid
的元素,但越來越多網頁因為排版的需求,會將元素修改為 grid
屬性,下方範例展示 HTML 有設定 display:grid;
和沒有設定的 div 與其子元素的差異( 詳細的 grid 會在網格排版的教學裡介紹 )。
<!-- 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
虛擬元素:這個虛擬元素負責清單符號樣式,可透過清單樣式設定。
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 的預設值截然不同的感覺。
<!-- 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 能有更深的認識。
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~