iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0
Modern Web

意識界歸來的前端系列 第 19

透過認識 element tree、document tree、box、display type 來理解 HTML 排版

  • 分享至 

  • xImage
  •  

切版會透過 display 值來設置不同的佈局排版方式,以及常常出現的 box(盒、框)又是什麼?此篇主要透過 element tree、document tree、box、display type 的介紹,來理解不同的排版對齊方式是如何產生的。

  • element tree
  • document tree
  • box
  • display type

element tree

element tree 其中可以包含元素(HTML 標籤)、text node(可以包含文字的元素)。

若對於哪些標籤可以包含文字還不清楚,可以參考前面這篇文章哪些標籤不適合設置文字內容?


document tree

一個 HTML 由各式各樣標籤組合而成,又可以稱為 document tree。

可以簡單理解為一個網頁就是由 document tree 組成,而每個元素都會產生一個 DOM 節點,DOM 節點是個物件,並定義了該元素可以使用的屬性、方法、事件。

下方是一個基礎 HTML 架構範例。

<!DOCTYPE html>
<html lang="zh-tw">
    <head>
        <meta charset="UTF-8">
        <title>HTML 基礎架構</title>
    </head>        
    <body>
        <h1 class="title">HTML 基礎架構</h1>
    </body>
</html>

Tips

  • document 會指向 DOM tree(根節點)。
  • DOM 元素為一個物件,並定義了該元素可以使用的屬性、方法、事件。

下方演示 JS 透過 document 來操作 DOM

// 回傳一個集合,所有符合條件的元素
document.getElementsByTagName('body');

// 回傳一個集合,所有符合條件的元素
document.getElementByClassName('title');

DOM 節點常見的類型有,element node、text node、document node(根節點)、document type node(文件類型,例如:HTML 5 <!DOCTYPE html>),其他類型可以到 MDN 文件上查看。


box

每個元素都會產生一個盒子(box),可以想像 document tree 就是由很多個 box 所組成。

用網頁結構來說,最外層 <html> 就像是大盒子,裡面包了兩個盒子 <head><body>

上述講了這麼多 document tree,它很重要嗎?

非常重要,因為 CSS 選擇器就是透過 document tree 來將其渲染到畫面上。

box model

每個元素會根據不同 box model 來生成一個 principal box 以及 零個多個 box,而 生成的 box 基本上屬於子元素的 box,只有 principal box 才是代表元素本身。

主要會根據元素的 display 屬性值(例如:inline、block),來生成不同種類的 box model,不同的 box model 會決定 CSS 佈局的排版方式

box model 分為以下六種類別:

Outside:<display-outside>

Inside:<display-inside>

List Item:<display-listitem>

Internal:<display-internal>

Box:<display-box>

  • contents 元素本身不會生成任何 box,但其子元素、偽元素還是會生成框,並且元素內的文字會正常顯示,為了符合 box 生成、layout 佈局的目的,contents 元素(包括子元素、偽元素)必須在 element tree 中替換為其他內容。
  • none 元素以及子元素皆不會生成 box 和文字內容

Precomposed:<display-legacy>

  • CSS Level 2 對 display 使用了 single-keyword 語法,用於匹配相同佈局模式的 block-level and inline-level variants 所需要的關鍵字。(對應的關鍵字請參考下方圖片)

儘管關鍵字對應的語法組合兩者結果是相等的,但它們的 specified values(針對該元素指定的屬性值) 仍然是不同的。

下方圖為六種類別對應的 display 值。

Tips

  • list-item 會產生副作用,生成 ::marker 偽元素、none(因為被排除在 box tree 之外,因此該元素以及子層皆不會生成 box、文本)。
  • Outer display types(block、inline、run-in) 會影響 替換元素(replaced elements)。
  • 如果指定了 <display-outside> 的值卻沒有設置 <display-inside>,則元素的 inner display type 預設值為 flow
  • box 對應值(contents、none)的元素,沒有內部或外部顯示類型,因為它們根本不生成任何框。

display type

display 屬性定義了元素的顯示類型(display type),而元素生成的 box 又分為以下兩種類別。

inner display type

  • 決定了子元素的 flow layout(佈局)。
  • 對應的 display 值為:flow、flow-root、table、flex、grid 和 ruby。

outer display type

  • 決定了該元素(principal box)如何影響 flow layout(佈局)。
  • 對應的 display 值為:block、inline 和 run-in。

The two-value syntax

MDN Adapting to the new two-value syntax of display

CSS Display Module Level 3 規範中描述了 display 屬性對於 outer、inner 兩種類型的 two-value 語法,但由於瀏覽器支援度還尚未普及。

因此 Precomposed 的 display-legacy 方法允許使用單個關鍵字來匹配對應 two-value 語法,直到 two-value 擁有更好的支援度前,都建議使用 display-legacy 的方式來替代。

下方範例將 display 設置為,一個保有 flex 排版方式的行內元素。

// two-value 方式
.box {
  display: inline flex;
}

// display-legacy 方式
.box {
  display: inline-flex;
}

reference


上一篇
h1 標籤 logo 常見迷思
下一篇
box 大集合:principal box、inline-level box、block box
系列文
意識界歸來的前端30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言