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