CSS盒子模型總結.md
在使用CSS進行網頁佈局時,我們一定離不開的一個東西————盒子模型。盒子模型,顧名思義,盒子就是用來裝東西的,它裝的東西就是HTML元素的內容。或者說,每一個可見的 HTML 元素都是一個盒子,下面所說的盒子都等同於 HTML 元素。這裡盒子與 中的盒子又有點不同,這裡的盒子是二維的。
盒子的組成
一個盒子由外到內可以分成四個部分:margin(外邊距)、border(邊框)、padding(內邊距)、content(內容)。會發現margin、border、padding是CSS屬性,因此可以通過這三個屬性來控制盒子的這三個部分。而content則是HTML元素的內容。
盒子的大小
盒子的大小指的是盒子的寬度和高度。大多數初學者容易將寬度和高度誤解為width和height屬性,然而預設情況下width
height
屬性只是設定content(內容)部分的寬和高。盒子真正的寬和高按下面公式計算:
盒子的寬度 = 內容寬度 + 左填充 + 右填充 + 左邊框 + 右邊框 + 左邊距 + 右邊距
盒子的高度 = 內容高度 + 上填充 + 下填充 + 上邊框 + 下邊框 + 上邊距 + 下邊距
為了顯得專業一點,我們還可以用帶屬性的公式表示:
盒子的寬度 = width + padding-left + padding-right + border-left + border-right + margin-left + margin-right
盒子的高度 = height + padding-top + padding-bottom + border-top + border-bottom + margin-top + margin-bottom
上面說到的是 預設 情況下的計算方法,另外一種情況下,width
和height
屬性設定的就是盒子的寬度和高度。盒子的寬度和高度的計算方式由box-sizing屬性控制。
box-sizing
屬性值
content-box
:預設值,width和height屬性分別應用到元素的內容框。在寬度和高度之外繪製元素的內邊距、邊框、外邊距。
border-box
:為元素設定的width和height屬性決定了元素的邊框盒。就是說,為元素指定的任何內邊距和邊框都將在已設定的寬度和高度內進行繪製。通過從已設定的寬度和高度分別減去外邊距、邊框和內邊距才能得到內容的寬度和高度。
inherit
:規定應從父元素繼承box-sizing屬性的值。
盒子成分分析
margin
margin,盒子的外邊框,他是完全透明的,開發者只可以設定它的邊距。
margin包含了上下左右四條邊,開發者可以單獨設定每一條邊的邊距。
margin-top
:上邊距margin-buttom
:下邊距margin-left
:左邊距margin-right
:右邊距
開發者也可以直接使用簡寫屬性margin
同時設定四條邊的寬度。
margin示例1
/*margin屬性後只跟一個值,同時設定四條邊的邊距相等*/
margin: 10px;
/*下面樣式與上面的樣式等價*/
margin-top: 10px;
margin-right: 10px;
margin-bottom: 10px;
margin-left: 10px;
margin示例2
/*margin屬性後跟兩個值,第一個值設定上下邊距,第二個是設定左右邊距*/
margin: 10px 20px;
/*下面樣式與上面的樣式等價*/
margin-top: 10px;
margin-right: 20px;
margin-bottom: 10px;
margin-left: 20px;
margin示例3
/*margin屬性後跟三個值,第一個值設定上邊距,第二個是設定左右邊距,第三個值設定下邊距*/
margin: 10px 20px 30px;
/*下面樣式與上面的樣式等價*/
margin-top: 10px;
margin-right: 20px;
margin-bottom: 30px;
margin-left: 20px;
margin示例4
/*margin屬性後跟四個值,第一個值設定上邊距,第二個是設定右邊距,第三個值設定下邊距,第四個值設定左邊距*/
margin: 10px 20px 30px 40px;
/*下面樣式與上面的樣式等價*/
margin-top: 10px;
margin-right: 20px;
margin-bottom: 30px;
margin-left: 20px;
padding
padding表示盒子的內邊距(填充)。與外邊距不同,padding不是隻能完全透明的,可以設定背景顏色和圖片。
與margin類似,padding包含了上下左右四條邊,開發者可以單獨設定每一條邊的邊距。
padding-top
:上部填充padding-bottom
:下部填充padding-left
:左部填充padding-right
:右部填充
開發者也可以直接使用簡寫屬性padding
同時設定四條邊的寬度。這一部分的用法與上面的margin
類似,可以參考margin
的四個例項。
border
border表示盒子的邊界,它可以設定成可見的,樣式多樣的。
最基本的,border像margin和padding一樣可以分別對每一條邊進行設定,也可以使用簡寫屬性border進行設定。
border-top
:上邊界border-bottom
:下邊界border-left
:左邊界border-right
:右邊界
border例項1
/*使用簡寫屬性,同時設定四條邊界,四條邊界的寬度、樣式和顏色都是一樣的*/
border: 2px solid green;
/*下面的樣式與上面的樣式等價*/
border-top: 2px solid green;
border-bottom: 2px solid green;
border-left: 2px solid green;
border-right: 2px solid green;
除了可以單獨對每一條邊進行樣式設定之外,還可以分別對邊界的寬度、樣式和顏色進行設定(下面的屬性會對四條邊進行設定),同樣可以使用簡寫屬性border進行設定。
border-width
:邊界寬度border-style
:邊界樣式border-color
:邊界顏色
border-sytle
屬性可取值:
none
:定義無邊框。hidden
:與 “none” 相同。不過應用於表時除外,對於表,hidden 用於解決邊框衝突。dotted
:定義點狀邊框。在大多數瀏覽器中呈現為實線。dashed
:定義虛線。在大多數瀏覽器中呈現為實線。solid
:定義實線。double
:定義雙線。雙線的寬度等於 border-width 的值。groove
:定義 3D 凹槽邊框。其效果取決於 border-color 的值。ridge
:定義 3D 壟狀邊框。其效果取決於 border-color 的值。inset
:定義 3D inset 邊框。其效果取決於 border-color 的值。outset
:定義 3D outset 邊框。其效果取決於 border-color 的值。inherit
:規定應該從父元素繼承邊框樣式。
border例項2
/*使用簡寫屬性設定寬度、樣式和顏色,同時作用於四條邊*/
border: 2px dotted green;
/*下面的樣式與上面的樣式等價*/
border-width: 2px;
border-style: dotted;
border-color: green;
這還不算完,開發者還可以對單獨一條邊界單獨設定寬度、樣式或顏色。以上兩組屬性都可以作為下面屬性的簡寫屬性。
border-top-width
:上邊界寬度border-top-style
:上邊界樣式border-top-color
:上邊界顏色border-bottom-width
:下邊界寬度border-bottom-style
:下邊界樣式border-bottom-color
:下邊界顏色border-left-width
:左邊界寬度border-left-style
:左邊界樣式border-left-color
:左邊界顏色border-right-width
:右邊界寬度border-right-style
:右邊界樣式border-right-color
:右邊界顏色
border例項3
/*使用簡寫屬性設定寬度、樣式和顏色,同時作用於四條邊*/
border: 2px dotted green;
/*下面的樣式與上面簡寫樣式等價*/
border-width: 2px;
border-style: dotted;
border-color: green;
/*下面的樣式與上面簡寫樣式等價*/
border-top: 2px solid green;
border-bottom: 2px solid green;
border-left: 2px solid green;
border-right: 2px solid green;
/*下面樣式又與上面三個樣式的任意一個樣式等價*/
border-top-width: 2px;
border-top-style: dotted;
border-top-color: green;
border-bottom-width: 2px;
border-bottom-style: dotted;
border-bottom-color: green;
border-left-width: 2px;
border-left-style: dotted;
border-left-color: green;
border-right-width: 2px;
border-right-style: dotted;
border-right-color: green;
上面的屬性是對各邊的寬度、樣式和顏色進行設定,下面一些有趣的屬性可以讓盒子變得更加地有創意、更加好看。
首先,瞭解一下 邊界半徑 ,也就是圓角。邊界半徑由屬性border-radius
進行控制,這是一個簡寫屬性,像上面提到過的margin
、padding
等一樣,可以有一個、兩個、三個或四個值進行設定。同樣也可以對盒子的每一個角的半徑進行單獨設定。
border-top-left-radius
:左上角border-top-right-radius
:右上角border-bottom-left-radius
:左下角border-bottom-left-radius
:右下角
邊界半徑可以使用 px、em 等長度單位,也可以使用百分數。
border-radius
值的個數以及每個值對應控制的位置:
- 一個值:設定四個角有相同的邊界半徑;
- 兩個值:第一個值設定左上角和右下角,第二個值設定右上角和左下角;
- 三個值:第一個值設定左上角,第二個值設定右上角和左下角,第三個值設定右下角;
- 四個值:第一個值設定左上角,第二個值設定右上角,第三個值設定右下角,第四個之設定左下角。
border例項4
/*以簡寫屬性的三個值為例*/
border-radius: 10px 20px 30px;
/*下面樣式與上面簡寫屬性樣式等價*/
border-top-left-radius: 10px;
border-top-right-radius: 20px;
border-bottom-right-radius: 30px;
border-bottom-left-radius: 20px;
開發者還可以設定x半徑和y半徑的不同,建立橢圓形角。x半徑表示水平半徑,y半徑表示垂直半徑。在border-radius
屬性中,x半徑和y半徑用“/”分隔,在border-top-left
等四個屬性中,傳入兩個值,第一個值表示x半徑,第二個值表示y半徑。
border例項5
/*簡寫屬性的x半徑設定兩個值,y半徑設定三個值*/
border-radius: 30px 20px / 20px 10px 30px;
/*在簡寫屬性中設定角度時,值與盒子角的對映是x和y分開的,按照上面提到的規則進行對映*/
/*x半徑兩個值,第一個值控制左上角和右下角,第二個值控制右上角和左下角*/
/*y半徑三個值,第一個值控制左上角,第二個值控制右上角和左下角,第三個值控制右下角*/
border-top-left-radius: 30px 20px;
border-top-right-radius: 20px 10px;
border-bottom-right-radius: 30px 30px;
border-bottom-left-radius: 20px 10px;
圖形邊界
圖形邊界是用圖形來作為盒子的邊界border。我將這一部分單獨作為一個小節的原因是,圖形邊界border-image
是CSS3新增的內容,實現起來比較複雜,而且只有一些版本比較新的主流瀏覽器支援。
在這隻圖形邊界之前,需要先設定一個邊界,讓圖形有顯示的空間,同時也可以讓不支援圖形邊界的瀏覽器顯示這個預先設定好的非圖形邊界。然後,還需要將背景顏色和背景圖片限制在填充和內容之內(預設情況下,背景顏色和背景圖片作用在border,padding和content,邊界的樣式浮在背景之上),這需要用到background-clip
屬性。
background-clip
屬性的值:
- border-box:背景延伸到邊框外沿(但是在邊框之下)。
- padding-box:邊框下面沒有背景,即背景延伸到內邊距外沿。
- content-box:背景裁剪到內容區 (content) 外沿。
- text:背景被裁剪為文字的前景色(只有chrome支援)。
在圖形邊界中用到以下屬性:
border-image
:設定圖形邊界,簡寫屬性border-image-source
:圖形的來源(路徑),可以接收一個URL函式或一個漸變作為值。border-image-slice
:圖形的切片大小border-image-width
:圖形邊界的寬度border-image-repeat
:定義圖片如何填充邊框border-image-outset
:定義邊界內部和內邊距之間的額外空間的大小
可能有很多小夥伴看不懂,沒關係,下面對以上屬性進行詳細的解釋。
border-image-source
從圖形的來源開始說起。圖形的來源可以是一個圖片或者漸變顏色。設定圖片用URL(path)
函式,設定漸變顏色用linear-gradient(to top|bottom|left|right, beginColor1, endColor2)
函式。還有一個預設值none
,當使用預設值的時候,或者如果影象無法顯示,則使用邊框樣式border-style
。有了圖形還不行,還需要對圖形進行切割,才能夠應用到邊界上。
border-image-slice
該屬性將圖片切割成9個區域,包括四個角,四條邊以及中心區域。四條切片線,從它們各自的側面設定給定距離,控制區域的大小。
上圖中,四條切片線將圖片切成了9份。其中1、2、3、4為四個角區域,將會對應應用到盒子邊界的四個角;5、6、7、8為四個邊界區域,將會對應應用到盒子邊界的四條邊;區域9為中心區域,預設情況下會被丟棄,但如果設定了fill
關鍵字(可以被設定在屬性的任何一個位置(前面、後面或者兩個值之間)),則會將其作為背景圖形。
border-image-slice
屬性的值可以是數字或百分數,還有關鍵字fill
。值的個數可以是1-4個,其規則與margin
、padding
等屬性一樣。
border-image-repeat
該屬性設定圖片在邊框的填充方式。值的個數可以是一個或兩個,一個值時設定所有的邊框,兩個值時分別設定水平與垂直的邊框。它具有下面的值:
stretch
:拉伸圖片以填充邊框。repeat
:平鋪圖片以填充邊框。round
:平鋪影象。當不能整數次平鋪時,根據情況放大或縮小影象。space
:平鋪影象 。當不能整數次平鋪時,會用空白間隙填充在影象周圍(不會放大或縮小影象)inherit
:繼承父級元素的計算值。
border-image-width
設定圖形邊界的寬度。當border-image-width
的值大於border-width
時,圖形不會向margin方向擴充套件,而是會向padding和content方向擴充套件,覆蓋。
border-image-width
屬性的值可以是長度或百分數,以及auto。值的個數為1-4個,其規則與margin
、padding
等屬性的規則一致。
border-image-outset
該屬性設定邊框影象可超出邊框盒的大小。講的通俗一點,就是在影象和padding之間增加一些填充,將邊框影象往外擠。它的值可以是長度或百分數,值的個數為1-4個,其規則與margin
、padding
等屬性的規則一致。
border-image
該屬性是一個簡寫屬性,他可以設定上面提到的五個屬性,其基本語法如下:
<'border-image-source'> || <'border-image-slice'> [ / <'border-image-width'> | / <'border-image-width'>? / <'border-image-outset'> ]? || <'border-image-repeat'>
關於“||”、“?”等符號的意義可以檢視CSS屬性值定義語法。
border-image例項
background:blue;
background-clip: padding-box;
border: 20px dotted green;
border-image:url(https://mdn.mozillademos.org/files/13060/border-image.png) 40 / 10px / 20px round;
/*其中border-image屬性可以用以下一組屬性代替*/
border-image-source: url(https://mdn.mozillademos.org/files/13060/border-image.png);
border-image-slice: 40;
border-image-width: 10px;
border-image-outset: 20px;
border-image-repeat: round;
盒子陰影
在盒子的組成成分之外,CSS3給盒子添加了陰影。盒子的陰影由box-shadow
屬性控制,陰影的輪廓與盒子邊界border的輪廓一樣。該屬性的正規語法如下:
none | [inset? && [ <offset-x> <offset-y> <blur-radius>? <spread-radius>? <color>? ] ]#
- inset:預設陰影在邊框外。使用 inset 後,陰影在邊框內(即使是透明邊框),背景之上內容之下。
- :這是頭兩個長度值,用來設定陰影偏移量,相對於border外邊線開始計算。 設定水平偏移量,如果是負值則陰影位於元素左邊。設定垂直偏移量,如果是負值則陰影位於元素上面。如果兩者都是0,那麼陰影位於元素後面。這時如果設定了 或 則有模糊效果。
- :這是第三個長度值。值越大,模糊面積越大,陰影就越大越淡。 不能為負值。預設為0,此時陰影邊緣銳利。
- :這是第四個長度值。取正值時,陰影擴大;取負值時,陰影收縮。預設為0,此時陰影與元素同樣大。
- :如果沒有指定,則由瀏覽器決定——通常是color的值,不過目前Safari取透明。
設定多個陰影時,使用逗號將每個陰影的值隔開。前面的陰影會在後面陰影之上,如果上層有透明度較低的部分,會與下層的顏色重疊,合成新顏色。
border-shadow例項
/* offset-x | offset-y | color */
box-shadow: 60px -16px teal;
/* offset-x | offset-y | blur-radius | color */
box-shadow: 10px 5px 5px black;
/* offset-x | offset-y | blur-radius | spread-radius | color */
box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);
/* inset | offset-x | offset-y | color */
box-shadow: inset 5em 1em gold;
/* 多個陰影*/
box-shadow: 3px 3px red, -1em 0 0.4em olive, 5px 10px 5px 5px green;
/*全域性關鍵字*/
box-shadow: inherit;
box-shadow: initial;
box-shadow: unset;
瀏覽器相容性
本部分內容引用w3cSchool CSS教程的CSS盒子模型
一旦為頁面設定了恰當的 DTD,大多數瀏覽器都會按照上面的圖示來呈現內容。然而 IE 5 和 6 的呈現卻是不正確的。根據 W3C 的規範,元素內容佔據的空間是由 width 屬性設定的,而內容周圍的 padding 和 border 值是另外計算的。不幸的是,IE5.X 和 6 在怪異模式中使用自己的非標準模型。這些瀏覽器的 width 屬性不是內容的寬度,而是內容、內邊距和邊框的寬度的總和。
雖然有方法解決這個問題。但是目前最好的解決方案是迴避這個問題。也就是,不要給元素新增具有指定寬度的內邊距,而是嘗試將內邊距或外邊距新增到元素的父元素和子元素。
IE8 及更早IE版本不支援 填充的寬度和邊框的寬度屬性設。
解決IE8及更早版本不相容問題可以在HTML頁面宣告 <!DOCTYPE html>
即可。
參考
[1] w3cSchool CSS教程