css知多少(7)——盒子模型

王福朋發表於2015-02-12

1. 引言

  從這一節開始,我們就進入本系列的第三部分——css呈現。本部分將描述css在頁面的幾種佈局和呈現的特性。包括兩類:文字、塊。

  第一類——文字。這部分相對比較簡單一些,例如設定字號、字型、顏色、背景色、是否加粗等。重點的地方在於設定字型、設定行高、文字相關的距離都用相對值,這些東西在《css知多少(4)——解讀瀏覽器預設樣式》那一節已經說過了。另外還有一個重點,就是web端最流行的字型庫fontAwesome,關於它我之前有一篇文章專門講過,請參見《請用fontAwesome代替網頁icon小圖示》,這裡就不再重複去講了。

       第二類——塊。這部分的知識點非常多,重要的有:盒子模型,float,position,display。本文章講盒子模型,後面的文章會依次介紹其他的內容。

2. 什麼是“盒子”

  說道“盒子”我還記得好幾年之前,我還在上大學的時候,被人問道過“盒子模型”,我當時都不知道什麼意思。回到宿舍急忙上網去查,原來就是我早就知道的margin,padding和border,但是我竟然不知道“盒子”這個詞。——所以,不要只滿足於網上查來的程式碼段、小技巧,要全面的瞭解一些知識體系。當然,後來我又知道,盒子模型不僅僅是margin,padding和border,還有其他的知識。

  在此插一句題外話,也是我這幾天思考的一點東西。我在思考:web前端的這麼知識應該是怎樣的一個知識體系架構?之前我以為可以以W3C為綱要,把W3C的東西學會了就夠了。後來發現我錯了,W3C還不全面。

  真正全面的覆蓋了web前端知識體系的東西是——瀏覽器核心——這並不是說讓你去詳細瞭解瀏覽器核心、做出一個瀏覽器。瀏覽器是web前端程式碼執行的一個平臺,瀏覽器核心裡有哪些模組,我們就需要去學習哪些東西。詳細的先不說,以後有機會再分享。

  這裡照顧一下初學者。初學css的朋友,一開始學css基礎知識的時候一定學過padding,border和margin,即內邊距、邊框、外邊距。他們三者就構成了一個“盒子”。就像我們收到的快遞,本來買了一個小小的iphone,收到的確實那麼大一個盒子。因為iphone白色的包裝盒和iphone機器之間有間隔層(內邊距),iphone白色盒子有厚度,雖然很薄(邊框),盒子和快遞箱子之間還有一層泡沫板(外邊距)。這就是一個典型的盒子。

  

  如上圖,真正的內容就是這些文字,文字外圍有10px的內邊距,5px的border,10px的外邊距。看到盒子了吧?

3. 盒子的寬度

3.1.    設定了固定寬度的情況下

  遇到這種問題,我建議在查詢各種資料之前,不如先自己動手做一個實驗:

  

  如上圖,得到網頁效果之後,我們可以用截圖工具來量一下文字內容的寬度。發現,文字內容的寬度剛好是300px,就是我們設定的寬度。

  因此,在盒子模型中,我們設定的寬度都是內容寬度,不是整個盒子的寬度。而整個盒子的寬度是:(內容寬度 + border寬度 + padding寬度 + margin寬度)之和。這樣我們改四個中的其中一個,都會導致盒子寬度的改變。這對我們來說不友好。

  沒關係,這個東西不友好早就有人發現了,而且已經解決,下文再說。

3.2.    充滿父容器的情況下

  預設情況下,div的display:block,寬度會充滿整個父容器。如下圖:

  

  但是別忘記,這個div是個盒子模型,它的整個寬度包括(內容寬度 + border寬度 + padding寬度 + margin寬度),整個的寬度充滿父容器。

  問題就在這裡。如果父容器寬度不變,我們手動增大margin、border或padding其中一項的寬度值,都會導致內容寬度的減少。極端情況下,如果內容的寬度壓縮到不能再壓縮了(例如一個字的寬度),那麼瀏覽器會強迫增加父容器的寬度。這可不是我們想要看到的。

3.3.    包裹內容的情況下

  這種情況下比較簡單,內容的寬度按照內容計算,盒子的寬度將在內容寬度的基礎上再增加(padding寬度 + border寬度 + margin寬度)之和。

  

4. 再看盒子的寬度

  前面提到,為盒子模型設定寬度,結果只是設定了內容的寬度,這個不合理。如何解決這一問題?答案就是:box-sizing:border-box

  

  如上圖,div設定了box-sizing:border-box之後,300px的寬度是內容 + border + 邊框的寬度(不包括margin),這樣就比較符合我們的實際要求了。

  建議大家在為系統寫css時候,第一個樣式是:

      

  大名鼎鼎的bootstrap也把box-sizing:border-box加入到它的 * 選擇器中,我們為什麼不這樣做呢?

5. 縱向margin的重疊

  這裡提到margin,不得不提一下margin的這一特性——縱向重疊。如下圖,<p>的縱向margin是16px,那麼兩個<p>之間縱向的距離是多少?

  按常理來說應該是 16 + 16 = 32px,但是答案仍然是 16px。因為縱向的margin是會重疊的,大的會把小的“吃掉”(可以自己去實驗)。

      

6. 用div畫“三角”

  “三角”在日常的網頁中是很常見的,例如百度首頁:

  

  以及我的開源專案wangEditor(http://www.cnblogs.com/wangfupeng1988/p/4198428.html)中的頁面效果:

  

  你當然可以使用背景圖片、fontAwesome來實現這一效果,但是你也可以用div來實現這一效果,很簡單,而且可以封裝通用:

      

7. 總結

  這一節我們用不小的篇幅講解了盒子模型的相關知識,比較適合初學者,但是更加適合那些沒有系統學習過css的有經驗的開發人員,還是那句話:建議大家系統的學習知識體系。

  下面我們將繼續這一部分,再說一說float。

---------------------------------------------------------------

本系列的目錄頁面:http://www.cnblogs.com/wangfupeng1988/p/4325007.html

-------------------------------------------------------------------------------------------------------------

學習作者教程:《前端JS高階面試》《前端JS基礎面試題》《React.js模擬大眾點評webapp》《zepto設計與原始碼分析》《json2.js原始碼解讀

也歡迎關注我的開源專案——wangEditor,簡潔易用的web富文字編輯器

-------------------------------------------------------------------------------------------------------------

相關文章