BFC佈局規則:css
簡單示例:
1.自適應兩欄佈局
代碼以下:html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> body{ width:350px; position:relative; } div.sidebar{ float:left; width:100px; height:200px; background-color:#9deaf1; } div.main{ height:300px; background-color:#5dc2f6; } </style> </head> <body> <div class="sidebar"></div> <div class="main"></div> </body> </html>
頁面效果圖:css3
上述示例,正好反映了BFC佈局規則:每一個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此。
因此,sidebar雖然存在浮動,但main的左邊依然與包含塊的左邊相接觸。瀏覽器
2.BFC的區域不會與float box重疊。示例以下:app
代碼:ide
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> body{ width:350px; position:relative; } div.sidebar{ float:left; width:100px; height:200px; background-color:#9deaf1; } div.main{ height:300px; background-color:#5dc2f6; overflow:hidden; } </style> </head> <body> <div class="sidebar"></div> <div class="main"></div> </body> </html>
頁面效果圖:
經過overflow:hidden;觸發main的BFC,main區域沒有與float的sidebar重疊。說明了BFC的區域不會與float box重疊。佈局
3.計算BFC的高度時,浮動元素也參與計算。url
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> div.wrapper{ width:300px; border:2px solid #5dc2f6; } div.box{ width:100px; height:200px; background-color:#9deaf1; border:2px solid #5dc2f6; float:left; } </style> </head> <body> <div class="wrapper"> <div class="box"></div> <div class="box"></div> </div> </body> </html>
頁面效果圖:spa
咱們經過設計
div.wrapper{ width:300px; border:2px solid #5dc2f6; overflow:hidden; }
overflow:hidden; 觸發wrapper的BFC,
清除box的浮動帶來的影響,獲得的頁面效果圖以下:
所以說明:計算BFC的高度時,浮動元素也參與計算。
4.清除垂直邊距重疊
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> div.box{ width:100px; height:100px; background-color:#9deaf1; border:2px solid #5dc2f6; } div.m50{ margin-bottom:50px; } div.m100{ margin-top:100px; } </style> </head> <body> <div class="box m50"></div> <div class="box m100"></div> </body> </html>
頁面效果圖以下:
如圖所示,Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊。因此,兩個div的垂直距離變成了100px,而不是150px了。
若是咱們給第二個div套上一層wrapper,而且觸發外層的BFC,那麼兩個div就不是同一個BFC的兩個相鄰的Box了,而是變成兩個獨立的BFC。
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> div.box{ width:100px; height:100px; background-color:#9deaf1; border:2px solid #5dc2f6; } div.wrapper{ overflow:hidden; } div.m50{ margin-bottom:50px; } div.m100{ margin-top:100px; } </style> </head> <body> <div class="box m50"></div> <div class="wrapper"> <div class="box m100"></div> </div> </body> </html>
頁面效果圖以下:
垂直邊距再也不重疊,不是100px,而是150px了。
總結
以上事例都證實了:BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素。反之也如此。 由於BFC內部的元素和外部的元素絕對不會互相影響,所以, 當BFC外部存在浮動時,它不該該影響BFC內部Box的佈局,因此BFC經過改變本身的寬度,實現不與浮動box有重疊。一樣的,當BFC內部有浮動時,爲了避免影響外部元素的佈局,BFC計算高度時會包括浮動的高度。避免margin重疊也是這樣的一個道理。
一. 在觸發 hasLayout 的元素和建立了 Block Formatting Contexts 的元素中,浮動元素參與高度的計算
狀況1:沒有建立 Block formatting contexts 的塊級非替換元素,觸發了 IE 的 hasLayout。
分析如下代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hasLayout 和 BFC</title> <style> div.wrapper{ width:300px; } div#container{ background-color:#9deaf1; zoom:1; } span#span1{ background-color:#5dc2f6; } div#div1{ width:150px; height:50px; background-color:#0576b0; } div#div2{ float:left; background-color:#4dd5b3; } </style> </head> <body> <div class="wrapper"> <div id="container"> <span id="span1">simple text</span> <div id="div1">in flow</div> <div id="div2">float:left</div> </div> </div> </body> </html>
根據 CSS2.1 規範第 10.6.3部分的高度計算規則,在進行普通流中的塊級非替換元素的高度計算時,浮動子元素不參與計算。
因此,在進行 container 高度計算時,只受 span1 和 div1的影響,應該是它們兩個的高度之和,因此最終container 的高度不包括div2的高度。
頁面效果圖在各瀏覽器的效果以下:
IE6 IE7:
IE8 Firefox Chrome Safari Opera:
當去掉container的zoom:1;各瀏覽器表現一致:
狀況2:建立了 BFC的塊級非替換元素,未觸發 IE 的 hasLayout。
代碼以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hasLayout 和 BFC</title> <style> div.wrapper{ width:300px; } div#container{ background-color:#9deaf1; overflow:hidden; } span#span1{ background-color:#5dc2f6; } div#div1{ width:150px; height:50px; background-color:#0576b0; } div#div2{ float:left; background-color:#4dd5b3; } </style> </head> <body> <div class="wrapper"> <div id="container"> <span id="span1">simple text</span> <div id="div1">in flow</div> <div id="div2">float:left</div> </div> </div> </body> </html>
頁面效果圖以下:
IE6:
IE7/IE8/Firefox/Chrome/Safari/Opera
可見,只要 container 建立了 BFC,其浮動子元素就會參與其高度計算(IE7是因爲觸發了hasLayout 致使與其它瀏覽器的效果相同)。
二.與浮動元素相鄰的、觸發了 hasLayout 的元素或建立了 BFC 的元素,都不能與浮動元素相互覆蓋。
與浮動元素相鄰的、觸發了 hasLayout 的元素或建立了 Block formatting contexts的元素,都不能與浮動元素相互覆蓋。若是浮動元素的兩側有足夠的空間放置該元素,則元素會緊鄰浮動元素放置,必要時,該元素的寬度將會被壓縮。不然它們可能會定位到浮動元素的下方。
狀況1:沒有建立BFC的塊級非替換元素,觸發了 IE 的 hasLayout。
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hasLayout 和 BFC</title> <style> div#container{ border:2px solid #ddd; width:300px; height:150px; background:url("http://images0.cnblogs.com/ blog2015/790006/201508/041827351894332.png") repeat; } div#div1{ width:100px; height:100px; background-color:#9deaf1; float:left; filter:alpha("opacity=50"); opacity: 0.5; } div#div2{ background-color:green; zoom:1; } </style> </head> <body> <div id="container"> <div id="div1"> Float Block </div> <div id="div2"> 懷才就象懷孕,時間久了會讓人看出來。 </div> </div> </body> </html>
IE6:
IE7/IE8
Firefox/Chrome/Safari/Opera
根據 CSS 2.1 9.5 Floats 中的描述,浮動元素會覆蓋普通流中的塊容器。因此,div2 應該有一部分被 div1 覆蓋。
狀況2:建立了 BFC的塊級非替換元素,未觸發 IE 的 hasLayout。
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hasLayout 和 BFC</title> <style> div#container{ border:2px solid #ddd; width:300px; height:150px; background:url("http://images0.cnblogs.com/ blog2015/790006/201508/041827351894332.png") repeat; } div#div1{ width:100px; height:100px; background-color:#9deaf1; float:left; filter:alpha("opacity=50"); opacity: 0.5; } div#div2{ background-color:green; overflow:hidden; } </style> </head> <body> <div id="container"> <div id="div1"> Float Block </div> <div id="div2"> 懷才就象懷孕,時間久了會讓人看出來。 </div> </div> </body> </html>
Firefox/Chrome/Safari/Opera:
IE6:
IE7/IE8
三. 觸發 hasLayout 的元素和建立了 BFC的元素不會與它們的子元素髮生外邊距摺疊
狀況1:沒有生成BFC的塊級非替換元素,觸發了 IE 的 hasLayout。
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hasLayout和BFC</title> <style> div.box{ width:100px; height:100px; background-color:#9deaf1; border:2px solid #5dc2f6; } div.wrapper{ zoom:1; } div.m50{ margin-bottom:50px; } div.m100{ margin-top:100px; } </style> </head> <body> <div class="box m50"></div> <div class="wrapper"> <div class="box m100"></div> </div> </body> </html>
根據 CSS 2.1 8.3.1 Collapsing margins 第一條,兩個相鄰的普通流中的塊框在垂直位置的空白邊會發生摺疊現象。
經過zoom:1;在IE中觸發了hasLayout,因此,垂直邊距不重疊,爲150px。
而BFC未觸發,因此垂直邊距重疊,爲100px;
IE6/IE7:
IE8/Firefox/Chrome/Safari/Opera:
狀況2:生成 BFC的塊級非替換元素,未觸發 IE 的 hasLayout。
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> div.box{ width:100px; height:100px; background-color:#9deaf1; border:2px solid #5dc2f6; } div.wrapper{ overflow:hidden; } div.m50{ margin-bottom:50px; } div.m100{ margin-top:100px; } </style> </head> <body> <div class="box m50"></div> <div class="wrapper"> <div class="box m100"></div> </div> </body> </html>
IE6:
IE7/IE8/Firefox/Chrome/Safari/Opera:
IE7此時觸發了hasLayout,但IE6沒有觸發hasLayout。
區別
共同點
可能產生的兼容性問題:
因爲 hasLayout 和 BFC是對一類事物的不一樣理解,而且他們的啓用條件不盡相同,所以若是一個元素設計時,在 IE 早期版本中觸發了 hasLayout ,但在其餘瀏覽器中又沒有建立BFC,或者相反,一個元素在 IE 早期版本中沒有觸發 hasLayout ,在其餘瀏覽器中卻建立了 BFC(如設置了 ‘overflow:hidden’ ),將致使頁面佈局的重大差別。
解決方案
僅當一個元素即在 IE 早期版本中觸發了 hasLayout,又在其餘瀏覽器中建立了BFC時,才能避免上述問題的發生。即同時啓用上述二者以保證各瀏覽器的兼容,或者相反,二者皆不啓用。 使元素即生成了BFC,又觸發了 hasLayout 對於觸發 hasLayout 的元素,經過 CSS 設置,使它產生BFC; 生成 BFC可是沒有觸發 hasLayout 的元素,經過設置 ‘zoom:1’,使其觸發 hasLayout。 使元素即沒有觸發 hasLayout,又沒有建立 BFC。
若有錯誤或者不足的地方,還望指正!----妙瞳
文章參考資料:
http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html
http://w3help.org/zh-cn/causes/RM8002