CSS葵花寶典——盒模型

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,left4個方向單獨進行設(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)都透明的。

從實踐來看

  • marginpadding都可以用來把盒子和盒子分開

    但是padding還可以把內(nèi)容和border分開

  • margin存在Margin Collapse的特點,padding不會存在

    Margin Collapse`深入的內(nèi)容,參看透析Margin Collapsing

建議:實際開發(fā)看著辦就好,只要保持用margin和padding使用習(xí)慣上的統(tǒng)一就OK

更多關(guān)于marginpadding的討論,參見 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-boxheightwidth僅僅是content的高度和寬度,并不包括paddingborder。所以你在考慮這個盒子占用的空間時,需要手動算上paddingborder

有時候莫名其妙水平方向有了滾動條、或則父元素寬度不夠,都是因為忽略了paddingborder的寬度。

下邊的這個列子會因為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,高度和寬度就會包含paddingborder,這樣才符合我們的習(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

我們說過,頁面中的每個元素都是一個盒子,blockinline 是大多數(shù)元素的默認(rèn)類型。元素以什么樣的方式展現(xiàn)出來,不是根據(jù)它是什么元素,而是由display屬性決定。

舉例說明——塊級元素、行內(nèi)元素

常說的塊級元素行內(nèi)元素實際包含兩個方面:

  1. HTML的嵌套規(guī)則

    一般塊級元素可以包含行內(nèi)元素和其他塊級元素,而行內(nèi)元素內(nèi)不可嵌套塊級元素

  2. 用戶代理默認(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)是blockheightwidthmargin-toppadding-left均有效,單獨占一行,注意它的margin-left/right和width的關(guān)系!

第二個p標(biāo)簽,dislplay: inlineheightwidthmargin-top都無效了

第三個p標(biāo)簽,display: inline-block。一切正常,而且不換行

block, inline, inline-block 總結(jié)

block

  • (默認(rèn))寬度:等于父元素content的寬度
  • (默認(rèn))高度:由子元素高度確定
  • width、height 可設(shè)置
  • 單獨占一行

inline

  • 設(shè)置widthheight無效
  • marginpadding 垂直方向上設(shè)置無效
  • 只要寬度足夠,從左往右(對于從左往右閱讀的語言)挨個排列

inline-block

inline-block繼承了inlineblock的特點,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è)置widthheight
  • marginpadding垂直方向上有效
  • 不換行

The Display Declaration這篇文章有更多的display屬性的演示和說明

挑戰(zhàn)一下

搞懂 displayblock, inline, inline-block 后,很多頁面你都可以完成了。實現(xiàn)Google開發(fā)者網(wǎng)站我們的截圖部分:

建議你拿我們最開始舉例的Google開發(fā)者網(wǎng)站練手,要求如下:

  • 不允許用浮動
  • 你要解決 inline-block 可能出現(xiàn)的空白問題
CSS 盒模型 任務(wù)

我這不直接貼代碼了,如果實現(xiàn)有問題或者需要參考的,直接聯(lián)系我就好了

原文地址:CSS葵花寶典——盒模型-4光年

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,755評論 2 371

推薦閱讀更多精彩內(nèi)容