你不得不瞭解的HTML知識

weixin_34054866發表於2016-12-27

這次要細說的只是塊級元素和行內元素的內容,如有不對,請輕噴。

塊級元素和行內元素

預設情況下塊級元素會始終佔居一行,而行內元素並不會。除了 table 元素的 display 屬性比較特殊以外,基本上所有的 HTML 元素的 display 的屬性值要麼是 block,要麼是 inline。無論你想了解哪個 HTML 元素,第一個要問的問題就是:它是塊級元素還是行內元素,然後在編寫標記的時候預想到這個元素在初始狀態下是如何定位的,這樣才能進一步想好將來怎麼用 CSS 重新定位它,因為塊級元素和行內元素在定位上有很大的區別,後面會詳細說明。

塊級元素盒子(一個很重要的概念————盒模型)會擴充套件到與父元素同寬,這也是為什麼塊級元素會佔居一行的原因了,因為所有塊級元素的父元素都是 body,而它的預設寬度就是瀏覽器的視口大小,所以預設情況下塊級元素的寬度也和瀏覽器的視口一樣寬,這樣以來,一個塊級元素旁邊也就沒有空間來容納另一個塊級元素了。

相比於塊級元素會擴充套件到與父元素同寬,然而行內元素的行為卻是恰恰相反,它會盡量的收縮包裹其內容,這也就是為什麼幾個行內元素會並排顯示在一行直到它們排滿一行才會另起一行,而每個塊級元素會直接另起一行的原因了。

下表列出了一些常見的塊級元素和行內元素:

塊級元素 行內元素
div span
form a
table img
header label
aside input
section select
article textarea
figure br
figcaption i
h1~h6 em
nav strong
p small
pre button
blockqoute sub
canvas sup
ol, ul, dl code

之前提到過無論你想了解哪個 HTML 元素,第一個要問的問題就是:它是塊級元素還是行內元素,因為它們在盒模型上的表現有很大的不同,不過在瞭解它們的不同之前我們還得先知道另外一個概念————替換元素非替換元素,其中替換元素就是指瀏覽器是根據元素的屬性來判斷具體要顯示的內容的元素,比如 img 標籤,瀏覽器是根據其 src 的屬性值來讀取這個元素所包含的內容的,常見的替換元素還有 inputtextareaselectobjectiframevideo 等等,這些元素都有一個共同的特點,就是瀏覽器並不直接顯示其內容,而是通過其某個屬性的值來顯示具體的內容,比如瀏覽器會根據 input 中的 type 的屬性值來判斷到底應該顯示單選按鈕還是多選按鈕亦或是文字輸入框。而對於非替換元素,比如 plabel 元素等等,瀏覽器這是直接顯示元素所包含的內容。看到這裡你應該大概的知道了什麼是替換元素和非替換元素了。

對著兩個概念有了大概的瞭解後就可以對 blockinline 在盒模型上的表現差異進行了解了,首先是 marginW3C 對其所支援了元素物件是這麼定義的:

Applies to: all elements except elements with table display types other than table-caption, table and inline-table

我的理解就是所有元素都支援 margin 除了 display 屬性值為 table-captiontable-inline 以外的所有表格顯示型別比如table-row-grouptable-celltable-rowtable-header-group等等,但是為了驗證我的理解,我發現 display 屬性值為 table 的元素也支援,可能是我對原文標準的理解有誤。但還有一個要特別注意的是 margin-topmargin-bottom 兩個屬性比較特殊,它們對非替換行內元素沒有效果,下面是 W3C 上對於 margin-topmargin-bottom 支援物件的介紹:

Applies to: all elements except elements with table display types other than table-caption, table and inline-table
These properties have no effect on non-replaced inline elements.

前面一句和之前對 margin 的描述是一樣的,這毫無疑問,下面這句話的意思是這些( margin-topmargin-bottom )屬性對非替換行內元素沒有效果比如 aspan,注意這裡是非替換行內元素而不單單是非替換元素或者是行內元素。比如 img 就是一個行內元素, margin-topmargin-bottom 對它是有效果的,因為它是一個替換元素而不是非替換元素,所以對於「 margin-topmargin-bottom 對行內元素沒有效果」這種說法是不對的。

而對於 padding 的支援物件,W3C 是這麼描述的:

all elements except table-row-group, table-header-group, table-footer-group, table-row, table-column-group and table-column

上面這句話的意思是除了表格顯示型別為 table-row-grouptable-header-grouptable-footer-grouptable-row,table-column-grouptable-column 的元素不支援,其他所有的元素都支援。

但這裡有些特殊情況需要注意的是,對行內元素比如 spanimg 設定左右內邊距的效果是可見可,但是對行內元素設定上下內邊距在有些情況下是不可見的,這些情況又要分為是否為替換元素和是否設定了背景色,為了能更直觀的瞭解這些概念,我在這裡做了個表格:

padding-top和padding-bottom 對於行內元素是否可見 替換元素(e.g: input) 非替換元素(e.g: span)

設定背景色
可見
影響行高
會撐開父元素
可見
不影響行高
不會撐開父元素

沒有設定背景色
可見
影響行高
會撐開父元素
不可見
不影響行高
不會撐開父元素

所以對於「 padding-toppadding-bottom 對行內元素沒有效果」這種說法也是不對的,因為它們只是對於沒有設定背景色的行內非替換元素效果不可見而已,而對於行內替換元素來說,不管是否設定了背景色都是有效果了,並且會把父元素撐開。

說了這麼多 blockinline 的區別,其實除了這兩個常見的 display 屬性以外還有一個屬性也是非常常見的,那就是 inline-block ,沒錯,這就是前面兩種情況的結合體,它既有 block 的特性又有 inline 的特性,比如把一個 display 屬性值為 block 或者 inline 的元素屬性值設定成 inline-block 後,既可以用只對行內元素有效的 text-align: center; 宣告對其進行居中以外,還可以用 padding-toppadding-bottom 對元素設定上下內邊距而無需對其設定背景色,並且能把父元素撐開。

不要問我為何知道這麼多,我只獻上傳送門

相關文章