在講 BFC 以前,咱們先來了解一下常見的定位方案,定位方案是控制元素的佈局,有三種常見方案:css
在普通流中,元素按照其在 HTML 中的前後位置至上而下佈局,在這個過程當中,行內元素水平排列,直到當行被佔滿而後換行,塊級元素則會被渲染爲完整的一個新行,除非另外指定,不然全部元素默認都是普通流定位,也能夠說,普通流中元素的位置由該元素在 HTML 文檔中的位置決定。html
在浮動佈局中,元素首先按照普通流的位置出現,而後根據浮動的方向儘量的向左邊或右邊偏移,其效果與印刷排版中的文本環繞類似。佈局
在絕對定位佈局中,元素會總體脫離普通流,所以絕對定位元素不會對其兄弟元素形成影響,而元素具體的位置由絕對定位的座標決定。post
Formatting context(格式化上下文) 是 W3C CSS2.1 規範中的一個概念。它是頁面中的一塊渲染區域,而且有一套渲染規則,它決定了其子元素將如何定位,以及和其餘元素的關係和相互做用。flex
那麼 BFC 是什麼呢?spa
BFC 即 Block Formatting Contexts (塊級格式化上下文),它屬於上述定位方案的普通流。3d
具備 BFC 特性的元素能夠看做是隔離了的獨立容器,容器裏面的元素不會在佈局上影響到外面的元素,而且 BFC 具備普通容器所沒有的一些特性。code
通俗一點來說,能夠把 BFC 理解爲一個封閉的大箱子,箱子內部的元素不管如何翻江倒海,都不會影響到外部。orm
只要元素知足下面任一條件便可觸發 BFC 特性:cdn
咱們在佈局時常常會遇到這個問題:對子元素設置浮動後,父元素會發生高度塌陷,也就是父元素的高度變爲0。解決這個問題,只須要把父元素變成一個BFC就好了。經常使用的辦法是給父元素設置overflow:hidden。
<style> .box1{ width:100px; height:100px; float:left; border: 1px solid #000; } .box2{ width:100px; height:100px; float:left; border: 1px solid #000; } .box{ background:yellow } </style>
<body>
<div class="box">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>
複製代碼
因爲容器內兩個div元素浮動,脫離了文檔流,父容器內容寬度爲零(即發生高度塌陷),未能將子元素包裹住。解決這個問題,只須要把把父元素變成一個BFC就好了。經常使用的辦法是給父元素設置overflow:hidden。
在CSS當中,相鄰的兩個盒子的外邊距能夠結合成一個單獨的外邊距。這種合併外邊距的方式被稱爲摺疊,而且於是所結合成的外邊距稱爲摺疊外邊距。
摺疊的結果:
這個一樣能夠利用BFC解決。 若是想要避免外邊距的重疊,能夠將其放在不一樣的 BFC 容器中。
<style> p{ color: #fff; background: #888; width: 200px; line-height: 100px; text-align:center; margin: 100px; } </style>
<body>
<p>ABC</p>
<p>abc</p>
</body>
複製代碼
上面例中兩個P元素之間距離本該爲200px,然而實際上只有100px,發生了margin重疊。遇到這種情形,咱們如何處理? 只須要在p外面包裹一層容器,並觸發該容器生成一個BFC。那麼兩個P便不屬於同一個BFC,就不會發生margin重疊了。
<style> p{ color: #fff; background: #888; width: 200px; line-height: 100px; text-align:center; margin: 100px; } .wrap{ overflow:hidden; } </style>
<body>
<p>ABC</p>
<div class="wrap">
<p>abc</p>
</div>
</body>
複製代碼
<style> .box{ width:100px; height:100px; background:#ccc; } .wrap { background:yellow; } .wrap h1{ background:pink; margin:40px; } </style>
<body>
<div class="box">box</div>
<div class="wrap">
<h1>h1</h1>
</div>
</body>
複製代碼
上圖wrap元素與h1元素之間l理論上本該有個40px的上下margin值,然而實際上父子元素並無存在margin值,與此同時,兩個div元素的間距爲40px。遇到這種情形,咱們如何處理? 處理方法其實有不少,**在wrap元素中添加:overflow:hidden;或者overflow:auto;使其父元素造成一個BFC;也能夠在wrap元素中添加border:1px solid;或是padding:1px;**這些均可以有效解決父子元素margin重疊問題。
這個方法能夠用來實現兩列自適應佈局,也就是左邊的寬度固定,右邊的寬度自適應。若是咱們改變文字的大小或者左邊浮動元素的大小,兩欄佈局的結構依然沒有改變!
<style> *{ margin: 0; padding: 0; } .box { width:300px; border: 1px solid #000; } .img { float: left; } .info { background: #f1f1f1; color: #222; } </style>
<body>
<div class="box">
<img src="03.jpg" alt="" class="img">
<p class="info">信息信息信息信息信息信息</p>
</div>
</body>
複製代碼
通常狀況下,它是這樣的
可是當文字多了之後...
顯然,這是文字受到了圖片浮動的影響。固然,若是你想作文本繞排的效果,浮動是不二之選。不過在這裏,這顯然不是咱們想要的。此時咱們能夠爲P元素的內容創建一個BFC,讓其內容消除對外界浮動元素的影響。給文字加上overflow:hidden
兩欄佈局就完成了。咱們改變圖片的大小:
兩欄佈局的結構依然沒有改變,如此就實現了兩欄自適應佈局。