下面咱們以<div><div>爲例子。<div></div>標籤被瀏覽器解析後會生成div元素並添加到document tree中,但CSS做用的對象並非document tree,而是根據document tree生成的render tree,而盒子模型就是render tree的節點。css
* 注意:
* 1. CSS做用的是盒子(Box), 而不是元素(Element);
* 2. JS沒法直接操做盒子。html
盒子模型的結構瀏覽器
因爲塊級盒子在驗證效果時干擾信息更少,便於理解盒子模型,所以下面將以塊級盒子模型來說解。
注意: 行級盒子模型與塊級盒子模型結構一致,只是行級盒子在此基礎上有自身特性而已。
從上面兩幅圖說明盒子模型其實就是由如下4個盒子組成:
1. content box:必備,由content area和4條content/inner edge組成;
2. padding box:可選,由padding和4條padding edge組成。若padding寬度設置爲0,則padding edge與content edage重疊;
3. border box:可選,由border和4條border edge組成。若border寬度設置爲0,則border edge與padding edage重疊;
4. margin box:可選,由margin和4條margin/outer edge組成。若margin寬度設置爲0,則margin edge與border edage重疊。
對於剛接觸CSS的同窗,常常會將"經過width/height屬性設置div元素的寬/高"掛在口邊,其實這句話是有誤的。
1. 首先css屬性width和height做用於div元素所產生的盒子,而不是元素自己;
2. 另外盒子模型由4個盒子組成,那width和height究竟是做用於哪些盒子呢?
這裏就分爲IE盒子模型和標準盒子模型了。佈局
IE5.5(怪異模式)採用IE盒子模型,其它將使用W3C標準盒子模型。flex
width = content-width + padding-width + border-width height = content-height + padding-height + border-height
標準盒子模型
width = content-width
height = content-height
咱們看到存在兩種width/height的劃分方式,到底哪一種纔對呢?其實兩種都對,具體看如何使用而已。另外IE8開始支持CSS3屬性box-sizing,讓咱們能夠自由選擇採用哪一種盒子:)
box-sizing:content-box/border-box/inherit
content-box——默認值,採用Standard box model
border-box——採用IE box model
inherit——繼承父元素屬性值
IFCspa
IFC(Inline Formatting Context),直譯爲「行內格式化上下文」。咱們簡單理解爲每一個盒子都有一個FC特性,不一樣的FC值表明一組盒子不一樣的排列方式。有的FC值表示盒子從上到下垂直排列,有的FC值表示盒子從左到右水平排列等等。而IFC則是表示盒子從左到右的水平排列方式,僅此而已(注意:一個盒子僅且僅有一個FC值)。而inline-level box的FC特性值固定爲IFC。另外僅處於in-flow的盒子才具備FC特性,也就是positioning scheme必須爲Normal flow的盒子才具備FC特性。3d
除了IFC外,對於inline-level box排版而言還有另外一個重要的對象,那就是line box。line box是一個看不見摸不着的邊框,但每一行所佔的垂直高度實際上是指line box的高度,而不是inline-level box的高度。orm
line box的特色:
1. 同一行inline-level box均屬於同一個line box;htm
2. line box高度的計算方式https://www.w3.org/TR/CSS21/visudet.html#line-height對象
行級盒子小結
**就盒子模型而言**
1. inline-level box與block-level box結構一致;
2. content box的高度僅能經過屬性font-size來設置,content box的寬度則自適應其內容而沒法經過屬性width設置;
3. 當inline-level box的寬度大於containing block,且達到內容換行條件時,會將inline-level拆散爲多個inline-level box並分佈到多行中,而後當屬性direction爲ltr時,margin/border/padding-left將做用於第一個的inline-level box,margin/border/padding-right將做用於最後一個的inline-level box;若屬性direction爲rtl時,margin/border/padding-right將做用於第一個的inline-level box,margin/border/padding-left將做用於最後一個的inline-level box。
**垂直排版特性**
inline-level box排版單位不是其自己,而是line box。重點在於line box高度的計算。
1. 位於該行上的全部in-flow的inline-level box均參與該行line box高度的計算;(注意:是全部inline-level box,而不只僅是子元素所生成的inline-level box)
2. replaced elements, inline-block elements, and inline-table elements將以其對應的opaque inline-level box的margin box高度參與line box高度的計算。而其餘inline-level box則以line-height的實際值參與line box高度的計算;
3. 各inline-level box根據vertical-align屬性值相對各自的父容器做垂直方向對齊;
4. 最上方的box的上邊界到最下方的下邊界則是line box的高度。(表述不夠清晰,請參考實例理解)
IFC佈局規則:
框會從包含塊的頂部開始,一個接一個地水平擺放。
擺放這些框的時候,它們在水平方向上的外邊距、邊框、內邊距所佔用的空間都會被考慮在內。在垂直方向上,這些框可能會以不一樣形式來對齊:它們可能會把底部或頂部對齊,也可能把其內部的文本基線對齊。能把在一行上的框都徹底包含進去的一個矩形區域,被稱爲該行的行框。水平的margin、padding、border有效,垂直無效。不能指定寬高。
行框的寬度是由包含塊和存在的浮動來決定。行框的高度由行高計算這一章所描述的規則來決定。
行框必定會高到足以容納它所包含的所有框。然而,它也可能比它所包含的最高的框還要高(例如:這些框是以基線對齊)。當框 B 的高度小於包含它的行框時,則 B 在行框中垂直對齊的位置由’vertical-align’ 屬性來決定。當幾個行級框在水平方向上沒法塞得進同一個行框時,它們會被分佈在兩個或多個垂直堆放的行框中。行框會以既沒有垂直間距 也沒有重疊的方式被垂直堆放起來。
一般,行框的左邊緊貼其包含塊的左邊,而行框的右邊緊貼其包含塊的右邊。然而,浮動框能夠插在包含塊邊緣與行框邊緣之間。所以,儘管在同一個IFC中的行框一般有一樣的寬度(也就是其包含塊的寬度),但它們的寬度也可能受浮動讓水平可用空間減小的影響而有所改變。在同一個IFC中,行框的高度一般是變化的(例如:某一行包含了一個比較高的圖片,而其它行只包含文本)。
當一行上的行級框的總寬度小於包含它們的行框的寬度,則它們在行框內的水平分佈由’text-align’屬性來決定。
當一個行內框的寬度超過了行框的寬度,則它會被分割成幾個框,而這些框會分佈在幾個行框。若是此行內框不可分割(例如:單個字符、或語言指定的文字打斷規則不容許在此行內框中出現打斷、或該行內框受 white-space 屬性爲 nowrap或 pre 的影響),那麼該行內框溢出該行框。
行內框被分割的時候,外邊距、邊框和內邊距在出現分割的地方都沒有視覺效果。
**行高計算 ― ‘line-height’ 與 ‘vertical-align’ 屬性**
計算行框裏的各行內級框的高度。對於置換元素、行內塊元素、行內表格元素來講,這是邊界框的高度,對於行內框來講,這是其 ‘line-height’。
行內級元素根據其 ‘vertical-align’ 屬性垂直對齊。
行框的高是最頂端框的頂邊到最底端框的底邊的距離。
BFC
BFC(Block Formatting Context)塊級格式化上下文
BFC則是表示盒子從上到下的垂直排列方式,僅此而已(注意:一個盒子僅且僅有一個FC值)。
實現BFC: