box model應該是CSS當中最核心的概念之一了,本篇主要講述CSS當中的box model(盒模型)。css
在看本篇內容以前,能夠先本身回答下面幾個問題:html
CSS2.1 specification 8.box model 第一句話就很好的描述了它的定義:react
The CSS box model describes the rectangular boxes that are generated for elements in the document tree and laid out according to the visual formatting model.瀏覽器
從這句話中咱們能夠得出來box model
是什麼: box model
是用來描述DOM樹中元素生成的矩形盒子的,而且UAs會根據 visual formatting model
來佈局這些盒子。bash
這一小節是用來描述具體的矩形盒子的,每一個盒子會有4塊區域:佈局
padding
, border
, margin
能夠被分割成top, bottom, left, right
四個小區域,並由具體的屬性來定義。下面咱們來引入新的名詞(爲了後面的內容),edge
: 每一個盒子的周長被稱爲edge
,即邊界。相應的,咱們能夠知道每一個box都會有四個edge
.flex
width
和 height
兩個屬性,元素的內容以及它的containing block決定Note: 一個box的content area, padding area 和 border area的 background樣式由該元素的 background
屬性決定。也就是說background
默認會一直延伸到 border area,而 margin老是透明的。在CSS3中,咱們可使用background新屬性來修改默認狀況。flexbox
CSS Box model 3 新增長一段: When a box fragments—is broken, as across lines or across pages, into separate box fragments—each of its boxes (content box, padding box, border box, margin box) also fragments. How the content/padding/border/margin areas react to fragmentation is specified in [css-break-3] and controlled by the box-decoration-break property.spa
這一段主要講的是當一個盒子跨行或者跨頁時會被分割成多個box片斷,那麼對於該盒子的content,padding,border,margin在不一樣的box 片斷中該如何表現?這些內容定義在css-break-3中,而且可使用box-decoration-break
來控制。 另外其實在CSS2.1也有描述這樣的場景,在8.6中描述了inline box跨行時盒模型該如何表現。代理
margin-top
, margin-bottom
, margin-left
, margin-right
和 margin
這些屬性都是初學時就已經用的很熟的。所以,這裏只強調幾個注意事項: 先看屬性的定義
'margin-top', 'margin-bottom', 'margin-left', 'margin-right'
Value: `<margin-width>` | inherit
Initial: 0
Applies to: all elements except elements with table display types other than table-caption, table and inline-table
Inherited: no
Percentages: refer to width of containing block
Media: visual
Computed value: the percentage as specified or the absolute length
複製代碼
value
能夠是 <margin-width>
,包含3種具體的取值:
<length>
: 指定固定的寬度,好比3px
, 1em
等<percentage>
: 百分比取值在由computed value
轉換成used value
的時候計算,基數是generated box's containing block
的width
(也就是該元素的包含塊的width). 而若是containing block的width會依賴該元素,那麼具體表如今CSS 2.1中未定義的。margin-top
和 margin-bottom
對於 non-replaced inline elements
不起做用。margin-block-start
,margin-block-end
(這些屬性跟文檔的writing mode
相關)。(logical margin和physical margin控制的是一樣的margin區域,只是不一樣的表現形式而已。CSS3加入這個特性是由於不一樣國家的文檔排列形式是不同的,好比阿拉伯語就是從右往左寫的)Note: CSS3中添加的margin-trim
屬性因爲目前沒有任何瀏覽器支持,這裏不作介紹(當前時間爲2019年2月)。
在CSS當中,2個或多個盒子相鄰的垂直方向margins會合併成一個margin,這種合併被咱們稱爲collapse
(塌陷),而合併後的margin被叫作collapse margin
. 首先,咱們先強調一些margin不會合並的例外狀況:
clear
屬性致使元素位置移動產生的間隙)的元素的top margin和 bottom margin 存在相鄰的margin,該元素的相關margin會和緊挨着的兄弟元素的相鄰外邊距合併,但合併後的外邊距不會再和父級塊的下外邊距合併那麼,如何判斷兩個盒子的margin是相鄰的(adjoining)呢? 須要同時知足下面那幾個條件:
block-level boxes
,而且處於同一個block formatting model
。line box
, clearance
, padding
, border
將它們間隔開(這裏高度爲0的line box
會被忽略)。in-flow
孩子節點的上外邊距in-flow
中的兄弟節點的上外邊距in-flow
孩子節點的下外邊距block formatting model
,min-height
爲0,height的computed value爲0
或者auto
,沒有in-flow
孩子節點。另外須要注意的是摺疊外邊距也可以與另外一個外邊距相鄰,只須要其外邊距的任意一部分與另外一個外邊距相鄰就算。
Note:由上面的collapse margin 的定義咱們能夠得出如下的推論:
floated box
的margin和任何其餘盒子的margin都不會合並(包括它流內的孩子節點)- 由於 float box
不是流內的。block formatting context
的元素的margin不會與它的流內孩子節點的margin合併(好比floated box)inline-block
盒子的margin不會與其餘盒子的margin合併(包括它的流內孩子節點)- 建立了新的block formatting model
而且不是block-level box
.in-flow block-level box
的下外邊距會與相鄰的in-flow block-level
兄弟節點的上外邊距合併,除非該兄弟節點存在clearance
in-flow block element
的上外邊距會與它的第一個流內孩子節點(該孩子節點是block-level
盒子)的上外邊距合併,這裏須要該元素不存在top border
,不存在top padding
,而且孩子節點也沒有clearance
height
爲auto
而且min-height
爲0
的in-flow block-level box
的bottom margin
會與它的最後一個流內block-level
的孩子節點的bottom margin
合併,條件是該盒子沒有bottom padding
,bottom border
而且其孩子節點的bottom margin
沒有與具備clearance的top margin合併min-height
爲0
, 既沒有上下邊框,也沒有上下內邊距,height爲0或者auto,且不包含line box(而且全部流內孩子的外邊距都會合並)那麼合併後的margin該如何取值呢?
下面咱們討論最後一種特殊狀況: 若是一個盒子的上下外邊距相鄰,那麼有可能外邊距合併會穿透該盒子。在這種狀況下,該元素的位置取決於合併margin的其餘元素之間的關係:
須要注意的是,被摺疊外邊距穿過的元素的位置不影響其餘外邊距正要被合併的元素的位置,其上邊框邊界的位置僅僅是用於佈局這些元素的後代元素。
padding-top
, padding-right
, padding-bottom
, padding-left
和 padding
padding屬性定義了盒子的內邊距區域的寬度。
'padding-top', 'padding-right', 'padding-bottom', 'padding-left'
Value: `<padding-width>` | inherit
Initial: 0
Applies to: 除table-row-group,table-header-group,table-footer-group,table-row,table-column-group和table-column外的全部元素
Inherited: no
Percentages: 參照包含塊的寬度
Media: visual
Computed value: 指定的百分比或者絕對長度
複製代碼
padding屬性和margin屬性主要由下面幾個不一樣:
auto
和margin同樣的是,百分比的基數是generated box's containing block
的width
(也就是該元素的包含塊的width).
note:這裏的padding-top
等4個屬性仍然是physical 屬性。在CSS3當中添加了logical padding - padding-block-start
等。
'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width'
Value: `<border-width>` | inherit
Initial: medium
Applies to: 全部元素
Inherited: no
Percentages: N/A
Media: visual
Computed value: 絕對長度,或者'0',若是border style爲'none'或者'hidden'的話
複製代碼
對於border-width
須要注意:
<border-width>
只有關鍵字和<length>
這兩種選擇,關鍵字是thin
, medium
, thick
,大小依次變大,具體大小由用戶代理決定'border-top-color', 'border-right-color', 'border-bottom-color', 'border-left-color'
Value: `<color>` | transparent | inherit
Initial: 'color'屬性的值
Applies to: 全部元素
Inherited: no
Percentages: N/A
Media: visual
Computed value: 從'color'屬性取值的話,取'color'的計算值,不然,就按指定值
複製代碼
這裏須要注意的是: border-color
的初始值是 color
屬性的值,咱們有些時候能夠利用這個特性來實現一些特殊的要求。
對於每個line box, UAs必須爲每個元素產生的inline box渲染margin,border,padding以visual order的方式(而非logical order) 主要分爲兩種狀況:
direction: ltr
: 元素出現的第一個line box的最左端生成的盒子具備左外邊距,左邊框,左內邊距,而且元素出現的最後一個line box最右端生成的盒子具備右內邊距,有邊框,右外邊距direction: rtl
:元素出現的第一個line box的最右端生成的盒子具備右內邊距,有邊框,右外邊距,而且元素出現的最後一個line box的最左端生成的盒子具備左外邊距,左邊框,左內邊距