由于 CSS 作用的對象是 HTML ,所以作者在這章主要先講了一些基本的 HTML 標簽的用法和結構。
## 1.2 HTML 文檔剖析
作者在這節主要講了一個 HTML 頁面所需的最基本的文檔結構如下:
~~~
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!-- 這里是網頁內容 -->
</body>
</html>
~~~
首先?``?是 HTML5 中新的文檔類型聲明語法,相比 HTML4 的冗長文檔類型聲明語法來說 HTML5 是大大的簡化了。
### 1.2.2 塊級元素和行內元素
作者在這一節介紹了兩個比較重要的概念————塊級元素和行內元素,默認情況下塊級元素會始終占居一行,而行內元素并不會。除了 table 元素的 display 屬性比較特殊以外,基本上所有的 HTML 元素的 display 的屬性值要么是 block,要么是 inline。作者的一個思想是,無論你想了解哪個 HTML 元素,第一個要問的問題就是:它是塊級元素還是行內元素,然后在編寫標記的時候預想到這個元素在初始狀態下是如何定位的,這樣才能進一步想好將來怎么用 CSS 重新定位它,因為塊級元素和行內元素在定位上有很大的區別,后面的拓展會詳細說明。
塊級元素盒子(一個很重要的概念————盒模型,后面會詳細說明)會擴展到與父元素同寬,這也是為什么塊級元素會占居一行的原因了,因為所有塊級元素的父元素都是 body,而它的默認寬度就是瀏覽器的視口(viewport)大小,所以默認情況下塊級元素的寬度也和瀏覽器的視口一樣寬,這樣以來,一個塊級元素旁邊也就沒有空間來容納另一個塊級元素了。
相比于塊級元素會擴展到與父元素同寬,然而行內元素的行為卻是恰恰相反,它會盡量的「收縮包裹」其內容(也是盒模型的概念),這也就是為什么幾個行內元素會并排顯示在一行直到它們排滿一行才會另起一行,而每個塊級元素會直接另起一行的原因了。
拓展:
作者在這一節中并沒有對塊級元素和行內元素的一些其他特性進行詳細的解釋,在這里筆者對它們的一些特性知識進行拓展。首先先列出一些常見的塊級元素和行內元素:
~~~
<!-- 常見的塊級元素 -->
div, form, table, header, aside, section, article, figure, figcaption, h1~h6, nav, p, pre, blockqoute, canvas, ol, ul, dl
<!-- 常見的行內元素 -->
span, a, img, label, input, select, textarea, br, i, em, strong, small, button, sub, sup, code
~~~
之前作者提到過無論你想了解哪個 HTML 元素,第一個要問的問題就是:它是塊級元素還是行內元素,因為它們在盒模型上的表現有很大的不同,不過在了解它們的不同之前我們還得先知道另外一個概念————[替換元素](http://www.w3.org/TR/html5/rendering.html#replaced-elements)和[非替換元素](http://www.w3.org/TR/html5/rendering.html#non-replaced-elements),其中替換元素就是指瀏覽器是根據元素的屬性來判斷具體要顯示的內容的元素,比如?`img`?標簽,瀏覽器是根據其?`src`?的屬性值來讀取這個元素所包含的內容的,常見的替換元素還有?`input`?、`textarea`、?`select`、?`object`、?`iframe`?和?`video`?等等,這些元素都有一個共同的特點,就是瀏覽器并不直接顯示其內容,而是通過其某個屬性的值來顯示具體的內容,比如瀏覽器會根據?`input`?中的?`type`?的屬性值來判斷到底應該顯示單選按鈕還是多選按鈕亦或是文本輸入框。而對于非替換元素,比如?`p`、`label`?元素等等,瀏覽器這是直接顯示元素所包含的內容。看到這里你應該大概的知道了什么是替換元素和非替換元素了。
對著兩個概念有了大概的了解后就可以對?`block`?和?`inline`?在盒模型上的表現差異進行了解了,首先是?`margin`?,[W3C](http://www.w3.org/TR/CSS2/box.html#margin-properties)?對其所支持了元素對象是這么定義的:
> Applies to: all elements except elements with table display types other than table-caption, table and inline-table
英語不是很好,沒太明白這句話的意思,我的理解就是所有元素都支持?`margin`?除了?`display`?屬性值為?`table-caption`?和?`table-inline`?以外的所有表格顯示類型比如`table-row-group`、?`table-cell`、?`table-row`?和?`table-header-group`等等,但是為了驗證我的理解,我發先?`display`?屬性值為?`table`?的元素也支持,可能是我對原文標準的理解有誤。但還有一個要特別注意的是?`margin-top`?和?`margin-bottom`?兩個屬性比較特殊,它們對非替換行內元素沒有效果,下面是 W3C 上對于?`margin-top`?和`margin-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-top`?和?`margin-bottom`?)屬性對非替換行內元素沒有效果比如?`a`?和`span`,注意這里是**非替換行內元素**而不單單是非替換元素或者是行內元素。比如?`img`?就是一個行內元素,?`margin-top`?和?`margin-bottom`?對它是有效果的,因為它是一個替換元素而不是非替換元素,所以對于「?`margin-top`?和?`margin-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-group`、?`table-header-group`、?`table-footer-group`、?`table-row`,?`table-column-group`?和?`table-column`?的元素不支持,其他所有的元素都支持。
但這里有些特殊情況需要注意的是,對行內元素比如?`span`?和?`img`?設置左右內邊距的效果是可見可,但是對行內元素設置上下內邊距在有些情況下是不可見的,這些情況又要分為是否為替換元素和是否設置了背景色,為了能更直觀的了解這些概念,我在這里做了個表格:

所以對于「?`padding-top`?和?`padding-bottom`?對行內元素沒有效果」這種說法也是不對的,因為它們只是對于沒有設置背景色的行內非替換元素效果不可見而已,而對于行內替換元素來說,不管是否設置了背景色都是有效果了,并且會把父元素撐開。
說了這么多?`block`?和?`inline-block`?的區別,其實除了這兩個常見的?`display`?屬性以外還有一個屬性也是非常常見的,那就是?`inline-block`?,沒錯,這就是前面兩種情況的結合體,它既有?`block`?的特性又有?`inline`?的特性,比如把一個?`display`?屬性值為?`block`?或者?`inline`?的元素屬性值設置成?`inline-block`?后,既可以用只對行內元素有效的?`text-align: center;`?聲明對其進行居中以外,還可以用?`padding-top`?和?`padding-bottom`?對元素設置上下內邊距而無需對其設置背景色,并且能把父元素撐開。
對于塊級元素和行內元素的拓展就暫時到這,如果有不明白或者不對的地方也歡迎指出。
## 1.3 文檔對象模型
作者在這一小節只要介紹了 HTML 結構所對應的文檔對象模型(DOM,Document Object Model),DOM 是從瀏覽器的視角來觀察頁面中的元素以及每個元素的屬性,由此可以得出這些元素的一個家族樹。通過 DOM 可以很清晰的看出文檔中每個元素之間的關系。比如下面的 HTML 代碼的 DOM 的家族樹就如下圖:
~~~
<body>
<section>
<h1>The Document Object Model</h1>
<p>The page's HTML markup structure defines the DOM.</p>
</section>
</body>
~~~

上面是一個非常簡單的 DOM 結構圖,由此你可以和直觀的看出 HTML 文檔流中每個元素之間的關系,比如到底是父子元素還是兄弟元素。
## 1.4 小結
作者在本章主要講解了 HTML 標簽是怎么為內容提供結構的,以及每個元素會在屏幕上生成什么樣子的盒子,比如是行內盒子還是塊級盒子,最后又簡單的講解了什么是 DOM ,它是瀏覽器中文檔的模型,而 CSS 可以修改 DOM 中的元素樣式屬性,從而修改頁面本身的布局和外觀。