BFC 已是一個耳聽熟聞的詞語了,可是我對於BFC的概念以及應用場景一直都不是很明白,聽說搞懂BFC可讓咱們理解CSS中某些本來詭異的地方。今天着重去了解了一下,作了如下總結。
css
在解釋BFC以前,先說一下文檔流。咱們常說的文檔流其實分爲定位流、浮動流、普通流三種。而普通流其實就是指BFC中的FC。
html
FC(Formatting Context),直譯過來就是「格式化上下文」,它是頁面中的一塊渲染區域,有一套渲染規則,決定了其子元素如何佈局,以及和其餘元素之間的關係和做用。常見的FC有BFC(塊級格式化上下文)、IFC(行級格式化上下文)、GFC(網格佈局格式化上下文)、FFC(自適應格式化上下文)。本文着重介紹BFC,其他的就不在這裏深刻展開了
jquery
【1】常規流(Normal flow)git
【2】浮動(Floats)github
【3】絕對定位(Absolute positioning)瀏覽器
MDN上的解釋:塊格式化上下文(Block Formatting Context,BFC) 是Web頁面的可視化CSS渲染的一部分,是佈局過程當中生成塊級盒子的區域,也是浮動元素與其餘元素的交互限定區域。
app
BFC(Block Formatting Context)直譯爲「塊級格式化上下文」,是用於佈局塊級盒子的一塊渲染區域。它規定了內部的塊級如何佈局,而且與這個區域外部絕不相干。簡單的歸納爲:所謂的BFC就是CSS佈局的一個概念,是一塊區域,一個環境。
ide
上文提到BFC是一塊渲染區域,那這塊渲染區域到底在哪,它有多大,這些由生成BFC的元素決定,CSS2.1中規定知足下列CSS聲明之一的元素便會生成BFC。
wordpress
【1】根元素,即HTML元素佈局
【2】浮動元素:float值爲left
、right
【3】overflow值不爲 visible,爲 auto
、scroll
、hidden
【4】display的值爲inline-block
、inltable-cell
、table-caption
、table
、inline-table
、flex
、inline-flex
、grid
、inline-grid
【5】position的值爲absolute
或fixed
【1】內部的Box會在垂直方向上一個接一個的放置
【2】垂直方向上的距離由margin決定。(完整的說法是:屬於同一個BFC的兩個相鄰Box的margin會發生重疊(塌陷),與方向無關。)
【3】每一個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便浮動元素也是如此。(這說明BFC中子元素不會超出他的包含塊,而position爲absolute的元素能夠超出他的包含塊邊界)
【4】BFC的區域不會與float的元素區域重疊
【5】計算BFC的高度時,浮動子元素也參與計算
【6】BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面元素,反之亦然
BFC是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面元素,反之亦然。咱們能夠利用BFC的這個特性來作不少事。
【1】防止margin重疊(塌陷)
根據BFC佈局規則第【2】條:垂直方向上的距離由margin決定。(完整的說法是:屬於同一個BFC的兩個相鄰Box的margin會發生重疊(塌陷),與方向無關。)兩個p元素之間的距離應該爲(50+50)px,發生了margin重疊後,兩個p之間的距離爲50px
解決:咱們能夠在其中一個p外面包裹一層容器,並觸發該容器生成一個新BFC。那麼兩個P便不屬於同一個BFC,就不會發生margin重疊了。
<style> p { color: rgba(21, 22, 22, 0.972); background: rgb(231, 105, 2); width: 200px; line-height: 100px; text-align:center; margin: 50px; font-weight: bold; } </style> <body> <p>Hello</p> <p>Hi</p> </body>複製代碼
<style> .wrap { /* 新的BFC */ overflow: hidden; } </style>複製代碼
【2】清除內部浮動
根據BFC佈局規則第【5】條:計算BFC的高度時,浮動子元素也參與計算。parent內部元素浮動了,所以div的高度就坍塌了,要解決坍塌,就得清除浮動。
解決:爲達到清除內部浮動,咱們能夠觸發parent生成BFC,那麼parent在計算高度時,parent內部的浮動元素child也會參與計算。
<style> .parent { border: 5px solid rgb(231, 105, 2); width: 300px; } .child { border: 5px solid rgba(95, 179, 235, 0.972); width: 100px; height: 100px; float: left; } </style> <body> <div class="parent"> <div class="child"></div> <div class="child"></div> </div> </body>複製代碼
<style> .parent { border: 5px solid rgb(231, 105, 2); width: 300px; /* 新的BFC */ overflow: hidden; } </style>複製代碼
【3】自適應多欄佈局
根據BFC佈局規則第【3】條:每一個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便浮動元素也是如此。 所以,雖然存在浮動的元素aslide,但main的左邊依然會與包含塊的左邊相接觸。
解決:咱們能夠經過經過給main設置overflow:hidden來觸發main生成BFC, 當觸發main生成BFC後,這個新的BFC不會與浮動的aside重疊。所以會根據包含塊的寬度,和aside的寬度,自動變窄。從而實現自適應兩欄佈局。
<style> body { width: 400px; position: relative; } .aside { width: 100px; height: 150px; float: left; background: rgb(48, 44, 44); } .main { height: 200px; background: rgb(194, 189, 189); } </style> <body> <div class="aside"></div> <div class="main"></div> </body>複製代碼
<style> .main { /* 新的BFC */ overflow: hidden; height: 200px; background: rgb(194, 189, 189); } </style>複製代碼
【4】用於佈局
聖盃佈局和雙飛翼佈局,他們的都要求三列布局,中間寬度自適應,兩邊定寬,這樣作的優點是重要的東西放在文檔流前面能夠優先渲染。詳情連接:聖盃佈局&&雙飛翼佈局
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script> </head> <style> body { min-width: 550px; font-weight: bold; font-size: 20px; } #header, #footer { background: rgba(29, 27, 27, 0.726); text-align: center; height: 60px; line-height: 60px; } #footer { clear: both; } #container { padding-left: 200px; padding-right: 150px; overflow: hidden; } #container .column { position: relative; float: left; text-align: center; height: 300px; line-height: 300px; } #center { width: 100%; background: rgb(206, 201, 201); } #left { width: 200px; right: 200px; margin-left: -100%; background: rgba(95, 179, 235, 0.972); } #right { width: 150px; margin-right: -150px; background: rgb(231, 105, 2); } </style> <body> <div id="header">#header</div> <div id="container"> <div id="center" class="column">#center</div> <div id="left" class="column">#left</div> <div id="right" class="column">#right</div> </div> <div id="footer">#footer</div> </body> </html>複製代碼
參考: