本文最初發表於博客園,並在GitHub上持續更新前端的系列文章。歡迎在GitHub上關注我,一塊兒入門和進階前端。javascript
如下是正文。css
專業的面試,必定會問 CSS 盒模型。對於這個題目,咱們要回答一下幾個方面:html
(1)基本概念:content、padding、margin。前端
(2)標準盒模型、IE盒模型的區別。不要漏說了IE盒模型,經過這個問題,能夠篩選一部分人。java
(3)CSS如何設置這兩種模型(即:如何設置某個盒子爲其中一個模型)?若是回答了上面的第二條,還會繼續追問這一條。git
(4)JS如何設置、獲取盒模型對應的寬和高?這一步,已經有不少人答不上來了。github
(5)實例題:根據盒模型解釋邊距重疊。面試
前四個方面是逐漸遞增,第五個方面,卻鮮有人知。segmentfault
(6)BFC(邊距重疊解決方案)或IFC。api
若是能回答第五條,就會引出第六條。BFC是面試頻率較高的。
總結:以上幾點,從上到下,知識點逐漸遞增,知識面從理論、CSS、JS,又回到CSS理論。
接下來,咱們把上面的六條,依次講解。
標準盒子模型:
IE盒子模型:
上圖顯示:
在 CSS 盒子模型 (Box Model) 規定了元素處理元素的幾種方式:
CSS盒模型和IE盒模型的區別:
在 標準盒子模型中,width 和 height 指的是內容區域的寬度和高度。增長內邊距、邊框和外邊距不會影響內容區域的尺寸,可是會增長元素框的總尺寸。
IE盒子模型中,width 和 height 指的是內容區域+border+padding的寬度和高度。
代碼以下:
/* 設置當前盒子爲 標準盒模型(默認) */ box-sizing: content-box; /* 設置當前盒子爲 IE盒模型 */ box-sizing: border-box;
備註:盒子默認爲標準盒模型。
element.style.width/height;
缺點:經過這種方式,只能獲取行內樣式,不能獲取內嵌
的樣式和外鏈
的樣式。
這種方式有侷限性,但應該瞭解。
element.currentStyle.width/height;
獲取到的即時運行完以後的寬高(三種css樣式均可以獲取)。但這種方式只有IE獨有。
window.getComputedStyle(element).width/height;
方式三和方式二同樣。只不過,方式三能兼容 Chrome、火狐。是通用型方式。
element.getBoundingClientRect().width/height;
此 api 的做用是:獲取一個元素的絕對位置。絕對位置是視窗 viewport 左上角的絕對位置。
此 api 能夠拿到四個屬性:left、top、width、height。
總結:
上面的四種方式,要求能說出來區別,以及哪一個的通用型更強。
標準文檔流中,豎直方向的margin不疊加,只取較大的值做爲margin(水平方向的margin是能夠疊加的,即水平方向沒有塌陷現象)。
PS:若是不在標準流,好比盒子都浮動了,那麼兩個盒子之間是沒有margin重疊的現象的。
咱們來看幾個例子。
以下圖所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> * { margin: 0; padding: 0; } .father { background: green; } /* 給兒子設置margin-top爲10像素 */ .son { height: 100px; margin-top: 10px; background: red; } </style> </head> <body> <div class="father"> <div class="son"></div> </div> </body> </html>
上面的代碼中,兒子的height是 100px,magin-top 是10px。注意,此時父親的 height 是100,而不是110。由於兒子和父親在豎直方向上,共一個margin。
兒子這個盒子:
父親這個盒子:
上方代碼中,若是咱們給父親設置一個屬性:overflow: hidden
,就能夠避免這個問題,此時父親的高度是110px,這個用到的就是BFC(下一段講解)。
其實,這一小段講的內容與上一小段相同,都是講父子之間的margin重疊。
咱們來看一個奇怪的現象。如今有下面這樣一個結構:(div中放一個p)
<div> <p></p> </div>
上面的結構中,咱們嘗試經過給兒子p
一個margin-top:50px;
的屬性,讓其與父親保持50px的上邊距。結果卻看到了下面的奇怪的現象:
此時咱們給父親div加一個border屬性,就正常了:
若是父親沒有border,那麼兒子的margin實際上踹的是「流」,踹的是這「行」。因此,父親總體也掉下來了。
margin這個屬性,本質上描述的是兄弟和兄弟之間的距離; 最好不要用這個marign表達父子之間的距離。
因此,若是要表達父子之間的距離,咱們必定要善於使用父親的padding,而不是兒子的margin。
BFC(Block Formatting Context):塊級格式化上下文。你能夠把它理解成一個獨立的區域。
另外還有個概念叫IFC。不過,BFC問得更多。
BFC 的原理,其實也就是 BFC 的渲染規則(能說出如下四點就夠了)。包括:
(1)BFC 裏面的元素,在垂直方向,邊距會發生重疊。
(2)BFC在頁面中是獨立的容器,外面的元素不會影響裏面的元素,反之亦然。(稍後看舉例1
)
(3)BFC區域不與旁邊的float box
區域重疊。(能夠用來清除浮動帶來的影響)。(稍後看舉例2
)
(4)計算BFC的高度時,浮動的子元素也參與計算。(稍後看舉例3
)
有如下幾種方法:
方法1:overflow: 不爲vidible,可讓屬性是 hidden、auto。【最經常使用】
方法2:浮動中:float的屬性值不爲none。意思是,只要設置了浮動,當前元素就建立了BFC。
方法3:定位中:只要posiiton的值不是 static或者是relative便可,能夠是absolute
或fixed
,也就生成了一個BFC。
方法4:display爲inline-block, table-cell, table-caption, flex, inline-flex
參考連接:
下面來看幾個例子,看看如何生成BFC。
舉例1:解決 margin 重疊
當父元素和子元素髮生 margin 重疊時,解決辦法:給子元素增長一個父元素,給這個父元素建立BFC。
好比說,針對下面這樣一個 div 結構:
<div class="father"> <p class="son"> </p> </div>
上面的div結構中,若是父元素和子元素髮生margin重疊,咱們能夠給子元素建立一個 BFC,就解決了:
<div class="father"> <p class="son" style="overflow: hidden"> </p> </div>
由於第二條:BFC區域是一個獨立的區域,不會影響外面的元素。
舉例2:BFC區域不與float區域重疊:
針對下面這樣一個div結構;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .father-layout { background: pink; } .father-layout .left { float: left; width: 100px; height: 100px; background: green; } .father-layout .right { height: 150px; /*右側標準流裏的元素,比左側浮動的元素要高*/ background: red; } </style> </head> <body> <section class="father-layout"> <div class="left"> 左側,生命壹號 </div> <div class="right"> 右側,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae, </div> </section> </body> </html>
效果以下:
上圖中,因爲右側標準流裏的元素,比左側浮動的元素要高,致使右側有一部分會跑到左邊的下面去。
若是要解決這個問題,能夠將右側的元素建立BFC,由於第三條:BFC區域不與float box
區域重疊。解決辦法以下:(將right區域添加overflow屬性)
<div class="right" style="overflow: hidden"> 右側,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae, </div>
上圖代表,解決以後,father-layout
的背景色顯現出來了,說明問題解決了。
舉例3:清除浮動
如今有下面這樣的結構:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .father { background: pink; } .son { float: left; background: green; } </style> </head> <body> <section class="father"> <div class="son"> 生命壹號 </div> </section> </body> </html>
效果以下:
上面的代碼中,兒子浮動了,但因爲父親沒有設置高度,致使看不到父親的背景色(此時父親的高度爲0)。正所謂有高度的盒子,才能關住浮動。
若是想要清除浮動帶來的影響,方法一是給父親設置高度,而後採用隔牆法。方法二是 BFC:給父親增長 overflow=hidden
屬性便可, 增長以後,效果以下:
爲何父元素成爲BFC以後,就有了高度呢?這就回到了第四條:計算BFC的高度時,浮動元素也參與計算。意思是,在計算BFC的高度時,子元素的float box也會參與計算。
想學習代碼以外的軟技能?不妨關注個人微信公衆號:生命團隊(id:vitateam
)。
掃一掃,你將發現另外一個全新的世界,而這將是一場美麗的意外: