你所不知道的BFC

概述

BFC即Block Formatting Context。根據MDN上的定義,它是web頁面上CSS可視化渲染的一部分,表明了一個渲染區域,塊級元素在此區域中佈局、浮動元素在此區域中與其它元素互相做用。
通俗理解它是頁面佈局規則中的一小套規則,是頁面總體佈局中的mini佈局。BFC是一個容器,容器中按照必定的規則進行佈局,不會影響容器以外的其它元素。BFC容器的產生具備必定的條件,BFC是CSS佈局的基石。css

一. 觸發生成BFC的條件

根元素(<html>,能夠解釋頁面上正常流中block元素的行爲了)
浮動元素(元素的 float 屬性不是 none)
絕對定位元素(元素的 position屬性 爲 absolute 或 fixed)
行內塊元素(元素的 display 屬性爲 inline-block)
• 表格單元格(元素的 display 屬性爲 table-cell,HTML表格單元格默認爲該值)
• 表格標題(元素的 display屬性 爲 table-caption,HTML表格標題默認爲該值)
• 匿名錶格單元格元素(元素的 display 爲 table、table-row、 table-row-group、table-header-group、table-footer-group(分別是HTML table、row、tbody、thead、tfoot 的默認屬性)或 inline-table)
overflow 計算值(Computed)不爲 visible 的塊元素
display 值爲 flow-root 的元素
• contain 值爲 layout、content 或 paint 的元素
• 彈性元素(display 爲 flex 或 inline-flex 元素的直接子元素)
• 網格元素(display 爲 grid 或 inline-grid 元素的直接子元素)
• 多列容器(元素的 column-count 或 column-width (en-US) 不爲 auto,包括 column-count 爲 1)
• column-span 爲 all 的元素始終會建立一個新的BFC,即便該元素沒有包裹在一個多列容器中(標準變動,Chrome bug)html

二. BFC中的佈局規則

  1. Box會在垂直方向,一個接一個地放置;
  2. Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生合併,如後文中的圖4;
  3. 在BFC中,每個盒子的左外邊緣(margin-left)會觸碰到容器的左邊緣(border-left)(對於從右到左的格式來講,則觸碰到右邊緣);
  4. 對於浮動元素:BFC的區域不會與浮動盒子產生交集,而是緊貼浮動邊緣;計算BFC的高度時,也會檢測浮動或者定位的盒子高度。

三. 利用BFC能夠作什麼

1. 父容器包含浮動元素時高度發生塌陷

<div class="outer">
    <div class="float">我是一個左浮動元素.</div>
     此處是文本,文本的數量多得足夠包圍浮動的圖片的話,邊框將能夠框住總體
</div>
.outer {
    border: 5px dotted rgb(214,129,137); border-radius: 5px;width: 450px;padding: 10px;margin-bottom: 40px;
}
.float {
    padding: 10px;border: 5px solid rgba(214,129,137,.4);border-radius: 5px;background-color: rgba(233,78,119,.4); color: #fff;float: left; width: 200px;margin: 0 20px 0 0;
}

圖1-文本夠多,高度可包圍浮動元素:
image
圖2-文本少了,高度發生坍塌:
image
爲何會出現高度塌陷呢?
是由於當把元素設置爲浮動以後,它就脫離了正常的文檔流,此時因爲容器outer沒有設置高度,致使高度以其正常流中的文字高度爲準。浮動元素與容器邊框發生重疊。
有哪些解決辦法呢?
1.利用CSS的hack:清除浮動
2.利用本文中的BFC,把容器outer觸發成爲一個BFC,利用它能夠包裹浮動元素的特性。web

.outer {
    border: 5px dotted rgb(214,129,137);border-radius: 5px;width: 450px;padding: 10px;margin-bottom: 40px;
    /*解決方法 2:overflow: auto; 或者 display:flow-root;*/
    }
    /*解決方法 1:設置不可見的僞元素,清除浮動 */
.outer:after {
    visibility: hidden;display: block;content: "";clear: both;height: 0;
}

圖3:imageide

2. 垂直方向上外邊距合併

先看一段代碼,體會下什麼是外邊距合併。能夠看到,當爲兩個段落都設置爲10px的上下外邊距時,p一、p2之間實際只有一個10px,並不是20px。另外,若是不將container生成BFC,則p1段落的上外邊距也是不生效的,它會與div徹底重疊,如圖4。佈局

<div class="container">
    <p>我是container中的p1段落</p>
    <p>我是container中的p2段落</p>
</div>
.container {
    background-color: #ccc;
}
p { 
    background-color: rgb(233,78,119); 
    margin: 10px 0; 
}

圖4:image
對比圖4中的兩個差別,能夠看到將container轉變爲BFC區域後,p一、p2的上下外邊距生效。
爲了理解同一個BFC中的外邊距會發生合併,添加一個p3,並將它置於不一樣的BFC之中,從圖5能夠看到,此時,p3與p2之間即爲正常的距離20px。由此也能夠說明,BFC包含了它所含有的全部元素,但不包括建立了新BFC的子元素的內部元素。即人不可能同時踏入兩條河流,BFC也同樣,一個元素不可能同時屬於兩個BFC。flex

<div class="container">
    <p>我是container中的p1段落</p>
    <p>我是container中的p2段落</p>
    <div class="newBFC">
        <p>我是container中的p3段落</p>
    </div>
</div>
.container {
    background-color: #ccc;
    overflow: hidden;/* 將父容器設置爲BFC */
}
p { 
    background-color: rgb(233,78,119); 
    margin: 10px 0; 
}  
.newBFC {
    overflow: hidden; /* 建立一個新的BFC */
}

圖5:imageui

3. 自適應兩欄佈局的建立

前面的圖1展現了文本包裹浮動元素的狀況,如何設置文本不在包圍浮動,從而實現一個兩欄佈局呢?利用BFC,很容易實現。spa

<div class="outer">
        <div class="float">我是一個左浮動元素.</div>
        <div class="txt">此處是文本,將我設置爲一個BFC,我就再也不包圍浮動元素了,我本身玩本身的去咯~~~</div>
    </div>
.txt{
    border: 5px solid rgba(214,0,0,.4);
    border-radius: 5px;
    overflow: hidden; /* 建立一個新的BFC */
}

圖6:imagecode

四. BFC與文檔流、佈局的關係

經過上面的分析,能夠看出BFC在頁面佈局特別是塊級元素佈局是十分重要的。那麼BFC與文檔流又是什麼關係呢?文檔流即normal flow,是頁面中元素顯示的規則,經過position屬性和float屬性,能夠將元素從文檔流脫離,造成定位流和浮動流。
normal流其實就是指FC(Formatting Context),直譯過來是格式化上下文。FC它是頁面中的一塊CSS渲染區域,有一套渲染規則,決定了其子元素如何佈局,以及和其餘元素之間的關係和做用。常見的FC有BFC、IFC(Inline Formatting Contexts),還有GFC(GridLayout Formatting Contexts)和FFC(Flex Formatting Contexts)。orm

小結

本文首先概述了BFC的具體含義,並列出了如何能夠造成BFC的方法,而後介紹了BFC區域的佈局規則,並使用例子的方式重點介紹了利用BFC進行頁面佈局時能夠解決的問題:浮動元素致使的高度塌陷、外邊距合併問題以及自適應兩欄佈局的實現。最後還拓展介紹了BFC的兄弟、與頁面佈局中文檔流的關係。CSS知識點比較雜散,抓住重點、逐一擊破。加油~

參考文章:
understanding-css-layout-block-formatting-context
Block_formatting_context from MDN
BFC神奇背後的原理

相關文章
相關標籤/搜索