一、題目:談一談你對CSS盒模型的認識
專業的面試,一定會問 CSS 盒模型。對於這個題目,我們要回答一下幾個方面:
(1)基本概念:content、padding、margin。
(2)標準盒模型、IE盒模型的區別。不要漏說了IE盒模型,通過這個問題,可以篩選一部分人。
(3)CSS如何設置這兩種模型(即:如何設置某個盒子為其中一個模型)?如果回答了上面的第二條,還會繼續追問這一條。
(4)JS如何設置、獲取盒模型對應的寬和高?這一步,已經有很多人答不上來了。
(5)實例題:根據盒模型解釋邊距重疊。
前四個方面是逐漸遞增,第五個方面,卻鮮有人知。
(6)BFC(邊距重疊解決方案)或IFC。
如果能回答第五條,就會引出第六條。BFC是面試頻率較高的。
總結:以上幾點,從上到下,知識點逐漸遞增,知識面從理論、CSS、JS,又回到CSS理論。
二、接下來,我們把上面的六條,依次講解。
問題(1)
content就是內容區域,padding是內邊距,margin是外邊距,width和height則要根據是什麼模型決定
問題(2)標準盒模型和IE盒子模型
CSS盒模型和IE盒模型的區別:
在 標準盒子模型中,width 和 height 指的是內容區域的寬度和高度。增加內邊距、邊框和外邊距不會影響內容區域的尺寸,但是會增加元素框的總尺寸。IE盒子模型中,width 和 height 指的是內容區域+border+padding的寬度和高度。問題(3)CSS如何設置這兩種模型
備註:我們通常說的盒子默認為標準盒模型。
問題(4)JS如何設置、獲取盒模型對應的寬和高
方式一:通過DOM節點的 style 樣式獲取
缺點:通過這種方式,只能獲取行內樣式,不能獲取內嵌的樣式和外鏈的樣式。
這種方式有局限性,但應該了解。
方式二(通用型)
```
// window.getComputedStyle(element).width/height;
111
222
var oDiv1 = document.getElementById("div1");
console.log( window.getComputedStyle(oDiv1).width ) ;
```
這種方式能兼容 Chrome、火狐。是通用型方式。
方式三(IE獨有的)
```
//element.currentStyle.width/height;
var oDiv1 = document.getElementById("div1");
console.log( oDiv1.currentStyle.width);
```
和方式二相同,但這種方式只有IE獨有。獲取到的是運行完之後的寬高(三種css樣式都可以獲取)。
方式四
```
// element.getBoundingClientRect().width/height;
var oDiv1 = document.getElementById("div1");
console.log(oDiv1.getBoundingClientRect().width);
```
這種方式獲得到的寬度是內容content+padding+border
此 api 的作用是:獲取一個元素的絕對位置。絕對位置是視窗 viewport 左上角的絕對位置。
此 api 可以拿到四個屬性:left、top、width、height。
上面的四種方式,要求能說出來區別,以及哪個的通用型更強。
問題(5)margin塌陷/margin重疊
只有在標準文檔流中,而且是豎直方向的margin不疊加,只取較大的值作為margin
其他情況比如說,標準文檔流的水平方向的margin是可以疊加的,即水平方向沒有塌陷現象,and 如果不在標準流,比如盒子都浮動了,那麼兩個盒子之間是沒有margin重疊的現象的。
1.兄弟元素之間
2.子元素和父元素之間
對於上面那段代碼,兒子設了個上外邊距10px,那兒子不應該在父元素裡面往下竄10px嘛,而且父元素由於上面沒給高,所以搞應該是子元素100+margin10 =110px才對呀?然而,現實卻是子元素帶著父元素一塊往下竄了10px,而且父元素高度和子元素一樣是100px而不是110px,為啥子嘞?
因為兒子和父親在豎直方向上,共一個margin,margin塌陷
如果我們給父元素加個邊框border
或者我們給父元素設置一個屬性:overflow: hidden都可以避免這個問題
此時父親的高度是110px,這個用到的就是BFC(下一段講解)。
綜上
margin這個屬性,本質上描述的是兄弟和兄弟之間的距離; 最好不要用這個marign表達父子之間的距離。
所以,如果要表達父子之間的距離,我們一定要善於使用父親的padding,而不是兒子的margin。
問題(6)BFC(邊距重疊解決方案)
1.BFC的概念
BFC(Block Formatting Context):塊級格式化上下文。你可以把它理解成一個獨立的區域。
另外還有個概念叫IFC。不過,BFC問得更多。
2.BFC 的原理/BFC的布局規則【非常重要】
BFC 的原理,其實也就是 BFC 的渲染規則(能說出以下四點就夠了)。包括:
(1)BFC 內部的子元素,在垂直方向,邊距會發生重疊。
(2)BFC在頁面中是獨立的容器,外面的元素不會影響裡面的元素,反之亦然。(稍後看舉例1)
(3)BFC區域不與旁邊的float box區域重疊。(可以用來清除浮動帶來的影響)。(稍後看舉例2)
(4)計算BFC的高度時,浮動的子元素也參與計算。(稍後看舉例3)
3.如何生成BFC
有以下幾種方法:
方法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
5.BFC 原理解釋說明
(1)解決 margin 重疊
當父元素和子元素發生 margin 重疊時,解決辦法:給子元素或父元素創建BFC。
應用原理第二條:BFC區域是一個獨立的區域,不會影響外裡面的元素。
(2)清除浮動
上圖中,由於左側的小綠塊浮動了。所以下面的紅色塊就上去了,有一部分在綠塊下面
如果要解決這個問題,可以將右側的元素創建BFC,應用原理第三條:BFC區域不與float box區域重疊。解決辦法如下:(將right區域添加overflow屬性)
(3)清除浮動
現在有下面這樣的結構:
上面的代碼中,兒子浮動了,但由於父親沒有設置高度,導致看不到父親的背景色(此時父親的高度為0)。正所謂有高度的盒子,才能關住浮動。
如果想要清除浮動帶來的影響,方法一是給父親設置高度,然後採用隔牆法。方法二是 BFC:給父親增加 overflow=hidden屬性即可, 增加之後,效果如下:
為什麼父元素成為BFC之後,就有了高度呢?這就應用到了原理第四條:計算BFC的高度時,浮動元素也參與計算。意思是,在計算BFC的高度時,子元素的float box也會參與計算。