CSS假定每個元素都會生成一個或者多個矩形框,這稱為元素框(規(guī)范的將來版本可能允許非矩形框,不過對現(xiàn)在來說,框都是矩形的)。各元素框中心有一個內(nèi)容區(qū)(content area)。這個內(nèi)容區(qū)周圍有可選的內(nèi)邊框、邊框和外邊框。——《CSS權(quán)威指南》
任何一個頁面,都是由一個一個的盒子構(gòu)成;而每個元素,其實都是一個矩形盒子,也就是所謂的盒模型;所以,寫一個頁面,無非就是把這些盒子按照一定方式進行排列,是不很簡單——凡是都是盒子
以Google的開發(fā)者網(wǎng)站來展示:
先拆分成兩個大盒子(紅色虛線標(biāo)準(zhǔn)),然后在每個大盒子中又包括很多小盒子(你看,文字也是由矩形框包圍起來的),把這些盒子進行布局排版,再加上視覺效果,這個頁面就可以寫出來了。
盒模型基本結(jié)構(gòu)
扯了這么多,具體看看一個盒子是怎么樣的:
一個盒子,從內(nèi)到外,分別是content(內(nèi)容區(qū)域)
、padding內(nèi)邊距
、border(邊框)
、margin(外邊距)
;
而 padding
, border
, margin
都可以對 top
, right
,bottom
,left
4個方向單獨進行設(shè)置。
.box{
height: 300px; /* content 高度 */
width: 300px; /* content 寬度 */
border: 1px solid #333; /* 上下左右都是1px的邊框,顏色為#333的實線 */
margin-top: 80px; /* 僅設(shè)置 margin top */
padding: 40px; /* 上下左右都是 40px padding */
}
具體說下padding,margin四個方向的設(shè)置:
.box{
margin-top: 25px;
margin-bottom: 25px;
margin-left: 40px;
margin-right: 40px;
}
等同于
.box{
margin: 25px 40px;
}
等同于
.box{
margin: 25px 40px 25px 40px;
}
看明白了唄,設(shè)置padding或者margin的上下左右四個值,你可以單獨用
padding/margin-top
,padding/margin-bottom
,padding/margin-left
,padding/margin-right
有時候也可以直接為padding/margin
設(shè)置4個值(順序固定),從top
順時針繞一圈:
padding/margin: top right bottom left
還可以為padding
, margin
指定少于4個值,規(guī)則如下
如果缺少左外邊距,則使用右外邊距
如果缺少下外邊距,則使用上外邊距
如果缺少右外邊距,則使用上外邊距
padding和margin的區(qū)別
為了便于理解,你可以認(rèn)為,margin
是不屬于這個盒子的,僅僅是為了占據(jù)空間;而padding
是作為盒子的一部分。
從視覺上來講
padding的顏色是跟背景色一樣的,所以你給元素設(shè)置了背景色,padding也會受影響;而margin永遠(yuǎn)都透明的。
從實踐來看
-
margin
和padding
都可以用來把盒子和盒子分開但是
padding
還可以把內(nèi)容和border
分開 -
margin
存在Margin Collapse的特點,padding
不會存在Margin Collapse`深入的內(nèi)容,參看透析Margin Collapsing
建議:實際開發(fā)看著辦就好,只要保持用margin和padding使用習(xí)慣上的統(tǒng)一就OK
更多關(guān)于margin
和padding
的討論,參見 When to use margin vs padding in CSS
Box Sizing
寫 CSS 的時候,在 margin、padding、border存在的情況下,盒子實際占據(jù)的空間可能和預(yù)期不同,我們需要確定在 CSS 中 width,height 到底是包含哪些部分(content, padding, margin, border),具體的計算規(guī)則由 box-sizing 指定。
已知一個盒子的規(guī)則如下:
.box{
width: 300px;
height: 200px;
padding: 5px;
border: 2px solid;
}
問:這個盒子實際占據(jù)空間多大?
正確的計算如下:
實際占據(jù)空間寬度 =
width(300) + padding-left(5) + padding-right(5) + border-left(2) + border-right(2)
= 314px
content-box
我們的盒子的box-sizing
默認(rèn)值是content-box
:height
和width
僅僅是content
的高度和寬度,并不包括padding
和border
。所以你在考慮這個盒子占用的空間時,需要手動算上padding
和border
。
有時候莫名其妙水平方向有了滾動條、或則父元素寬度不夠,都是因為忽略了padding
和border
的寬度。
下邊的這個列子會因為border的存在而出現(xiàn)滾動條:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>測試</title>
<style type="text/css">
html, body{
width: 100%;
height: 100%;
}
.box{
border-left: 2px;
width: 100%;
}
</style>
</head>
<body>
<div class="box">Content Box</div>
</body>
</html>
border-box
如果將box-sizing
設(shè)置為border-box
,高度和寬度就會包含padding
和border
,這樣才符合我們的習(xí)慣。
修改上面的例子,避免出現(xiàn)滾動條,設(shè)置成border-box
就好了:
.box{
box-sizing: border-box;
}
box-sizing 實戰(zhàn)應(yīng)用
為了避免不必要的麻煩,建議將所有元素都設(shè)置成border-box
,推薦寫法:
html {
box-sizing: border-box;
}
*, *:before, *:after{
box-sizing: inherit;
}
注意,是通過為根元素html
設(shè)置border-box
,其他元素繼承實現(xiàn)的,而不是像這樣:
* {
box-sizing: border-box;
}
想想?yún)^(qū)別在哪,有啥好處
解釋在這:box-sizing best practices
display
不管是 div
也好, a
標(biāo)簽也好,在頁面中都是一個盒模型的實例,但每個盒子因為 display
屬性不同,又可以分為不同的類別(inline
, block
, inline-block
, table
等),在排版上有各自的特點。
The display CSS property specifies the type of rendering box used for an element. In HTML, default display property values are taken from behaviors described in the HTML specifications or from the browser/user default stylesheet. The default value in XML is inline.——MDN/CSS/display
我們說過,頁面中的每個元素都是一個盒子,block
、inline
是大多數(shù)元素的默認(rèn)類型。元素以什么樣的方式展現(xiàn)出來,不是根據(jù)它是什么元素,而是由display
屬性決定。
舉例說明——塊級元素、行內(nèi)元素
常說的塊級元素和行內(nèi)元素實際包含兩個方面:
-
HTML的嵌套規(guī)則
一般塊級元素可以包含行內(nèi)元素和其他塊級元素,而行內(nèi)元素內(nèi)不可嵌套塊級元素
-
用戶代理默認(rèn)
display
屬性值W3C為元素指定了默認(rèn)的
display
值,用戶代理(瀏覽器)根據(jù)W3C的標(biāo)準(zhǔn),實現(xiàn)默認(rèn)的樣式規(guī)則。W3C標(biāo)準(zhǔn):
瀏覽器默認(rèn)樣式
注: HTML5中已經(jīng)沒有行內(nèi)元素和塊級元素的概念,詳細(xì)參見Content categories,塊級元素大致相當(dāng)于HTML5中的Flow Elements,行內(nèi)元素相當(dāng)于Phrasing Elements
display 總結(jié)
- 元素以什么樣的盒子渲染,是通過display屬性控制,而非標(biāo)簽類型
- 瀏覽器默認(rèn)樣式為每個元素設(shè)置了
display
默認(rèn)值 -
display
默認(rèn)值是inline
(比如,某些瀏覽器不認(rèn)識HTML5中的標(biāo)簽,這些元素的display
屬性值就很悲劇都成inline
了) - 通過
display
僅僅是改變元素的顯示方式,并未改變標(biāo)簽類型
display
還有很多屬性值,感興趣的參看MDN display章節(jié)
block, inline, inline-block 區(qū)別
display
明白后,再看下 block
, inline
, inline-block
各自特點。
我們?yōu)?p
標(biāo)簽設(shè)置不同的 display
屬性:
HTML
<body>
<div>
block, inline, inline-block舉例:接下來是一個p標(biāo)簽:<p>display: block</p>,這是p標(biāo)簽之后的內(nèi)容。
</div>
<div>
block, inline, inline-block舉例:接下來是一個p標(biāo)簽,display設(shè)置為inline:<p class="inline">display: inline;</p>,這是p標(biāo)簽之后的內(nèi)容。
</div>
<div>
block, inline, inline-block舉例:接下來是一個p標(biāo)簽,display設(shè)置為inline-block:<p class="inline-block">display: inline-block</p>,這是p標(biāo)簽之后的內(nèi)容。
</div>
</body>
CSS
div{
margin-bottom: 3em;
border: 1px dotted #77C2D4;
}
p{
height: 2em;
width: 50%;
margin-top: 1em;
padding: 0 1em;
border: 1px dotted #F9454E;
}
.inline{
display: inline;
}
.inline-block{
display: inline-block;
}
效果圖
第一個p標(biāo)簽,默認(rèn)是block
。height
,width
,margin-top
,padding-left
均有效,單獨占一行,注意它的margin-left/right和width的關(guān)系!
第二個p標(biāo)簽,dislplay: inline
。height
,width
,margin-top
都無效了
第三個p標(biāo)簽,display: inline-block
。一切正常,而且不換行
block, inline, inline-block 總結(jié)
block
- (默認(rèn))寬度:等于父元素content的寬度
- (默認(rèn))高度:由子元素高度確定
- width、height 可設(shè)置
- 單獨占一行
inline
- 設(shè)置
width
和height
無效 -
margin
和padding
垂直方向上設(shè)置無效 - 只要寬度足夠,從左往右(對于從左往右閱讀的語言)挨個排列
inline-block
inline-block
繼承了inline
和block
的特點,W3chools的總結(jié)簡直完美:
An inline-block element is placed as an inline element (on the same line as adjacent content), but it behaves as a block element.
- 可設(shè)置
width
和height
-
margin
和padding
垂直方向上有效 - 不換行
The Display Declaration這篇文章有更多的display
屬性的演示和說明
挑戰(zhàn)一下
搞懂 display
和 block
, inline
, inline-block
后,很多頁面你都可以完成了。實現(xiàn)Google開發(fā)者網(wǎng)站我們的截圖部分:
建議你拿我們最開始舉例的Google開發(fā)者網(wǎng)站練手,要求如下:
- 不允許用浮動
- 你要解決
inline-block
可能出現(xiàn)的空白問題
我這不直接貼代碼了,如果實現(xiàn)有問題或者需要參考的,直接聯(lián)系我就好了
原文地址:CSS葵花寶典——盒模型-4光年