BFC(block formatting context):簡單來講,BFC 就是一種屬性,這種屬性會影響着元素的定位以及與其兄弟元素之間的相互做用。
中文譯爲塊級格式化上下文。是 W3C CSS 2.1 規範中的一個概念,它決定了元素如何對其內容進行定位,以及與其餘元素的關係和相互做用。 在進行盒子元素佈局的時候,BFC提供了一個環境,在這個環境中按照必定規則進行佈局不會影響到其它環境中的佈局。好比浮動元素會造成BFC,浮動元素內部子元素的主要受該浮動元素影響,兩個浮動元素之間是互不影響的。 也就是說,若是一個元素符合了成爲BFC的條件,該元素內部元素的佈局和定位就和外部元素互不影響(除非內部的盒子創建了新的 BFC),是一個隔離了的獨立容器。(在 CSS3 中,BFC 叫作 Flow Root)。css
其中,最多見的就是overflow:hidden、float:left/right、position:absolute。也就是說,每次看到這些屬性的時候,就表明了該元素已經建立了一個BFC了。html
6. 浮動盒區域不疊加到BFC上;chrome
BFC包含建立該上下文元素的全部子元素,但不包括建立了新BFC的子元素的內部元素,也就是一個元素不能同時存在於兩個BFC中。瀏覽器
通俗地來講:建立了 BFC的元素就是一個獨立的盒子,裏面的子元素不會在佈局上影響外面的元素,反之亦然,同時BFC仍然屬於文檔中的普通流。佈局
(1)包含浮動元素
問題案例:高度塌陷問題:在一般狀況下父元素的高度會被子元素撐開,而在這裏由於其子元素爲浮動元素因此父元素髮生了高度坍塌,上下邊界重合。這時就能夠用bfc來清除浮動了。
flex
(2)不被浮動元素覆蓋
問題案例: div浮動兄弟遮蓋問題:因爲左側塊級元素髮生了浮動,因此和右側未發生浮動的塊級元素不在同一層內,因此會發生div遮擋問題。能夠給藍色塊加 overflow: hidden,觸發bfc來解決遮擋問題。
spa
(3)BFC 會阻止外邊距摺疊
問題案例:margin塌陷問題:在標準文檔流中,塊級標籤之間豎直方向的margin會以大的爲準,這就是margin的塌陷現象。能夠用overflow:hidden產生bfc來解決。
.net
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>高度坍塌問題-BFC模式解析</title> <style> * { margin: 0; padding: 0; } .box{ background:#888; /* 灰色 */ height: 100%; margin-left: 50px; } .left{ background: #73DE80; /* 綠色 */ opacity: 0.5; border: 3px solid #F31264; width: 200px; height: 200px; float: left; } .right{ /* 粉色 */ background: #EF5BE2; opacity: 0.5; border: 3px solid #F31264; width:400px; min-height: 100px; } </style> </head> <body> <div class='box'> <div class='left'></div> <div class='right'></div> </div> </body> </html>
綠色框('#left')向左浮動,它建立了一個新BFC,但暫時不討論它所建立的BFC。因爲綠色框浮動了,它脫離了本來normal flow的位置,所以,粉色框('#right')就被定位到灰色父元素的左上角(特性3:元素左邊與容器左邊相接觸),與浮動綠色框發生了重疊。firefox
同時,因爲灰色框('#box')並無建立BFC,所以在計算高度的時候,並無考慮綠色框的區域,發生了高度坍塌,這也是常見問題之一。調試
如今經過設置overflow:hidden來建立BFC閉合浮動,再看看效果如何。
.BFC{ overflow: hidden; } <div class='box BFC'> <div class='left'> </div> <div class='right'> </div> </div>
灰色框建立了一個新的BFC後,高度發生了變化,計算高度時它將綠色框區域也考慮進去了(特性5:計算BFC的高度時,浮動元素也參與計算);而綠色框和紅色框的顯示效果仍然沒有任何變化。
如今,現將一些小塊添加到粉色框中,看看效果:
<style> .little{ background: #fff; width: 50px; height: 50px; margin: 10px; float: left; } </style> <div class='box BFC'> <div class='left'> </div> <div class='right'> <div class='little'></div> <div class='little'></div> <div class='little'></div> </div> </div>
因爲粉紅框沒有建立新的BFC,所以粉色框中白色塊受到了綠色框的影響,被擠到了右邊去了(特性6:浮動盒區域不疊加到BFC上)。先無論這個,看看白色塊的margin,發生了外邊距疊加。
利用同實例二中同樣的方法,爲粉色框建立BFC,防止與浮動元素(綠色框)重疊:
<div class='box BFC'> <div class='left'> </div> <div class='right BFC'> <div class='little'></div> <div class='little'></div> <div class='little'></div> </div> </div>
一旦粉色框建立了新的BFC之後,粉色框就不與綠色浮動框發生重疊了,同時內部的白色塊處於隔離的空間(特性4:BFC就是頁面上的一個隔離的獨立容器),白色塊也不會受到綠色浮動框的擠壓。
以上就是BFC的分析,BFC的概念比較抽象,但經過實例分析應該可以更好地理解BFC。在實際中,利用BFC能夠閉合浮動(實例二),防止與浮動元素重疊(實例四)。同時,因爲BFC的隔離做用,能夠利用BFC包含一個元素,防止這個元素與BFC外的元素髮生margin collapse。
float 脫離了普通流,而且建立了新的BFC,而父元素不具有產生 BFC 的條件,因此它的高度爲0。
如何解決?
經過了解BFC的特性咱們知道,BFC會把它包含的浮動元素高度也算在裏面,也就是閉合浮動。拿 overflow: auto 舉例:overflow: auto 並不會閉合浮動,而是 overflow: auto 會建立一個新的BFC,避免浮動的元素侵入其餘元素。
IE6-7有一個特有的屬性就是haslayout,當一個元素的hasLayout屬性值爲true時,咱們說這個元素有一個佈局(layout),它負責對本身和可能的後代元素進行尺寸計算和定位,當屬性值爲false時,它的尺寸和位置由最近擁有佈局的祖先元素控制。
不少狀況下,把 hasLayout的狀態改爲true 能夠解決很大部分ie下顯示的bug。 hasLayout屬性不能直接設定,經過設定一些特定的css屬性來觸發並改變 hasLayout 狀態。
元素hasLayout而致使的問題其實通常都很容易發現:每每是內容出現錯位甚至徹底不可見。 如:當一個元素內含浮動或絕對定位的內容時,它一般會表現出奇怪和錯誤的行爲
通常若是是由於layout而引發的顯示不符指望效果的話,在ff下會表現正常,而在ie下會出現錯誤。這個時候能夠嘗試觸發父容器及其中的子容器的haslayout屬性,一般能夠經過加上zoom: 1;來調試。直到找到了產生問題的元素,再進行鍼對性的修正。最好的辦法是對這個元素設置尺寸屬性。可是,有時不便指定尺寸屬性的狀況下,就只能尋找替代方案了。對於ie7 ,最好的辦法是設置最小高度屬性爲0;這個技術是無害的,由於0原本就是這個屬性的初始值。並且沒有必要對其餘瀏覽器隱藏這個屬性。而對於ie6和更早版本中觸發一個元素hasLayout的方法是在overflow屬性是visible的狀況下設置這個元素的高度屬性爲1%,而後對其餘瀏覽器隱藏這個設置。這種技術就是著名的Holly hack。
觸發hasLayout的條件:
position: absolute
float: left|right
display: inline-block
width: 除 「auto」 外的任意值
height: 除 「auto」 外的任意值 (例如不少人閉合浮動會用到 height: 1% )
zoom: 除 「normal」 外的任意值
writing-mode: tb-rl
在 IE7 中,一些額外的屬性也能夠觸發該屬性:
min-height: (任何值)
max-height: (任何值除了none)
min-width: (任何值)
max-width: (任何值除了none)
overflow: hidden|scroll|auto ( 這個屬性在IE以前版本中沒有觸發 layout 的功能。 )
overflow-x|-y: hidden|scroll|auto (CSS3 盒模型中的屬性,還沒有獲得瀏覽器的普遍支持。他們在以前IE版本中一樣沒有觸發 layout 的功能)
在支持BFC的瀏覽器(IE8+,firefox,chrome,safari)經過建立新的BFC閉合浮動;
在不支持 BFC的瀏覽器 (IE6-7),經過觸發 hasLayout 閉合浮動。
參考: 高度坍塌問題--BFC模式解析