BFC 在上一篇文章中, "清除浮動方法解析" ,我們談及了一些使用css屬性解決浮動帶來的影響。但是在解決浮動帶來的影響的方法中,如果細心思考,會產生如下疑問: 為什麼 可以清除浮動帶來的影響? 能否用其他css屬性清除浮動帶來的影響? 種種的疑問,會讓你覺得CSS真的不容易精通,說精通過於高大上 ...
BFC
在上一篇文章中,清除浮動方法解析,我們談及了一些使用css屬性解決浮動帶來的影響。但是在解決浮動帶來的影響的方法中,如果細心思考,會產生如下疑問:
- 為什麼
overflow
可以清除浮動帶來的影響? - 能否用其他css屬性清除浮動帶來的影響?
種種的疑問,會讓你覺得CSS真的不容易精通,說精通過於高大上,就連掌握都挺難的。
在清除浮動方法解析文章中,只是稍微說明瞭一下上面兩個問題的原因是BFC(塊級格式化上下文,Block Formatting Contexts)。在分享BFC之前,有必要談談另外一個概念。也就是可視化格式模型
可視化格式模型
我們知道,CSS元素可分為兩種,塊級元素和行內元素。塊級元素顯示為塊內容,對應著CSS元素框的‘塊框’。行內元素顯示在一行中,對應著CSS元素框的‘行內框’。
塊框在DOM中從上到下一個接一個地垂直排列,每一個塊框之間地垂直距離由框的垂直外邊距決定。如果在某個div內定義了一段純文本,此時這段純文本會被包含在匿名塊框內。
行內框在DOM中從左到右一個接一個地水平排列,由一行形成的水平框稱為行框,行框的高度總是足以容納它包含的所有行內框。行內框(行內元素)可以通過水平padding
、border
、margin
來改變兩兩行內框的水平間距。但是,垂直border
、padding
、margin
不影響兩兩行內框的垂直間距,同時垂直方向不占據任何空間。如果想要改變行內框(行內元素)的高度,可以使用line-height
來改變。
line-heignt主要用於控制行框的高度。
看個圖示。上為水平,下為垂直。
水平距離改變,垂直border不占據空間,因此擋住了文字。
W3school中指出,display
屬性可以規定某個元素生成框的類型。比如說,將某個行內元素設置display:block
,此時,行內元素對應的行內框因為display屬性的影響,行內框變成了塊框,即行內元素可以擁有像塊級元素一樣的特性。
BFC(Block Formatting Context,塊級格式化上下文)
知道可視化格式模型之後,我們來談談BFC。
我理解的BFC,其實就像一個隱藏技能,這種隱藏的技能是被動的,需要通過其他技能的使用才能發揮它的作用。在CSS中,BFC其實就是一個隱藏屬性,這種隱藏屬性需要其他特定的CSS屬性定義之後才會被觸發。當觸發了BFC這個隱藏屬性之後,就可以解決一系列的問題。
從可視化格式模型上來說,每一個塊框都可以看成是一個擁有隱藏的BFC屬性,在DOM中從上到下垂直排列,塊框之間的距離由外邊距決定。
普通文檔流的父級塊框就是自帶隱藏BFC屬性的,不同的塊框可能會在內部產生塊級格式化上下文。
觸發BFC的條件:
- 父級塊框自帶隱藏BFC屬性
- 浮動元素
- 絕對定位元素(包括
absolute
和fixed
) - 框類型
display
為:inline-block|table-cell|table-caption
overflow
屬性為hidden|auto|scroll
BFC可以解決的問題:
1.(BFC與margin)同一個父級塊框下,兄弟元素和父子元素的margin會發生重疊問題
2.(BFC與float)父元素高度塌陷問題、兄弟元素覆蓋問題
BFC與margin
margin重疊的解決方法:讓元素處於不同的BFC屬性環境下。
兄弟元素
在同一個父級塊框下,兄弟元素和父子元素的margin會發生重疊,並且這種重疊會遵循一定得規則:同號取大,異號相加。具體可以看看關於margin的介紹。傳送門:CSS margin
兄弟元素的margin重疊的解決方法:任一個兄弟元素的屬性設置如下:
float:left|right
或者position:absolute|fixed
或者display:inline-block|table-cell|table-caption
父子元素
父子元素的margin重疊解決方法:父元素設置以下任意屬性:overflow:hidden|auto|scroll
,或者給父元素設置padding
或border
屬性。
如果元素沒有垂直border
或者padding
,那麼父元素的高度就是它包含的子元素的頂部和底部邊框邊緣之間的距離。因此,包含的子元素的頂部和底部外邊距就突出到容器元素的外邊。因此,可以通過添加垂直border
或者padding
,外邊距就不會疊加了,而且父元素的高度就是它包含的子元素的頂部和底部外邊距邊緣之間的距離。
.father {
backgrund:blue;
width:500px;
height:50px;
margin-top:15px;
overflow:hidden; //padding:1px; //border:1px solid green;
}
.child {
height:30px;
width:500px;
background:pink;
margin-top:15px;
}
BFC與浮動
兄弟元素
在兩個兄弟元素a和b中,如果a元素設置了float屬性,b元素的佈局會受到影響,此時a元素會覆蓋在b元素上,如果b元素存在文字,那麼文字會環繞a元素顯示。
<div class="float"></div>
<div class="clearfloat">
沒有設置overflow:hidden|auto|scroll;沒有設置overflow:hidden|auto|scroll;沒有設置overflow:hidden|auto|scroll;
</div>
<div class="float"></div>
<div class="clearfloat">
設置overflow:hidden|auto|scroll設置overflow:hidden|auto|scroll設置overflow:hidden|auto|scroll空空空空補充內容
</div>
使其中一個兄弟元素觸發BFC之後就不會被其浮動元素覆蓋,使用這種float+overflow的方式可以實現一側固定,一側自適應的佈局效果。
父子元素
BFC與浮動如果針對父子元素,當然是解決父元素高度塌陷的問題了。
在W3C中指出 'Auto' heights for block formatting context roots。
也就是BFC會根據子元素的情況自動適應高度,即使其子元素中包括浮動元素。
給父元素設置以下任意屬性,觸發BFC隱藏屬性: overflow:hidden|auto|scroll
、 position:absolute
、float:left|right
、display:inline-block
父元素觸發BFC隱藏屬性前
父元素觸發BFC隱藏屬性後