概念
Formatting context
Formatting context 是 W3C CSS2.1 規(guī)范中的一個概念。它是頁面中的一塊渲染區(qū)域,并且有一套渲染規(guī)則,它決定了其子元素將如何定位,以及和其他元素的關(guān)系和相互作用。最常見的 Formatting context 有 Block fomatting context (簡稱BFC)和 Inline formatting context (簡稱IFC),CSS3還新增了GFC 和 FFC。
BFC(Block formatting context)
直譯為"塊級格式化上下文"。它是一個獨立的渲染區(qū)域,只有Block-level box參與, 它規(guī)定了內(nèi)部的Block-level Box如何布局,并且與這個區(qū)域外部毫不相干
IFC(inline formatting contenxt)
類似地,只有inline-level box參與,規(guī)定了內(nèi)部的inline-level box如何布局
BFC
名詞解釋

-
Block-level elements: display 為 block, list-item 或 table 元素 -
Block-level boxes:參與BFC的Block-level elements -
Block container box:一個容器,只包含Block-level boxes或只包含inline-level boxes(見后文)
注意,Block container box不一定是Block-level boxes,但如果的確都是則稱之為block boxes
創(chuàng)建BFC
滿足以下條件之一即可創(chuàng)建BFC
- 根元素或其它包含它的元素
- 浮動元素 (元素的 float 不是 none)
- 絕對定位元素 (元素具有 position 為 absolute 或 fixed)
- 內(nèi)聯(lián)塊 (元素具有 display: inline-block)
- 表格單元格 (元素具有 display: table-cell,HTML表格單元格默認(rèn)屬性)
- 表格標(biāo)題 (元素具有 display: table-caption, HTML表格標(biāo)題默認(rèn)屬性)
- 具有overflow 且值不是 visible 的塊元素,
- display: flow-root
- column-span: all 應(yīng)當(dāng)總是會創(chuàng)建一個新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一個多列容器中
布局規(guī)則
- 內(nèi)部的Box會在垂直方向,一個接一個地放置。
- Box垂直方向的距離由margin決定。屬于同一個BFC的兩個相鄰Box的margin會發(fā)生重疊
- 每個元素的margin box的左邊, 與包含塊border - box的左邊相接觸(對于從左往右的格式化,否則相反)。即使存在浮動也是如此。
- BFC的區(qū)域不會與float box重疊。
- BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此
- 計算BFC的高度時,浮動元素也參與計算
應(yīng)用
清除浮動造成的文字環(huán)繞
<div name="mydemocontainer" style="overflow:hidden;">
<div style="float:left">

</div>
<p class="oh">Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae hic ut ab perferendis sit quod architecto, dolor debitis quam rem provident aspernatur tempora expedita perspiciatis suscipit ipsam voluptas tenetur. Nostrum? Quae hic ut ab perferendis sit quod architecto. Quae hic ut ab perferendis sit quod architecto.
</p>
</div>
效果:
<iframe width="100%" height="300" src="http://jsrun.net/KBYKp/embedded/all/light/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
給p標(biāo)簽添加overflow:auto使得成為新的BFC,由于BFC的規(guī)則BFC的區(qū)域不會與float box重疊
清除浮動
<div class="par" style="border: 5px solid #fcc;width: 300px;">
<div class="child" style=" border: 5px solid #f66;width:100px;height: 100px;float: left;"></div>
<div class="child"></div>
</div>
效果:
<iframe width="100%" height="300" src="http://jsrun.net/pBYKp/embedded/all/light/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
給容器添加overflow:auto;后,使之成為BFC,根據(jù)規(guī)則計算BFC的高度時,浮動元素也參與計算,容器高度被float塊撐起,浮動的影響被清除
清除margin重疊
<div name="mydemocontainer" style="overflow:hidden;">
<div style="border: 5px solid #f66;width:100px;height: 100px;margin:10px;"></div>
<div style="border: 5px solid #f66;width:100px;height: 100px;margin:10px;"></div>
</div>
效果
<iframe width="100%" height="300" src="http://jsrun.net/kBYKp/embedded/all/light/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
兩個div在同一個BFC中,第一個div的下邊界margin與第二個上邊界margin重合,間距10px。給其中一個div再包裹一個div<div style="overflow:auto;">...</div>。根據(jù)規(guī)則屬于同一個BFC的兩個相鄰Box的margin會發(fā)生重疊,現(xiàn)在有margin的div的其中一個被包裹,那么兩個div不屬于同一個BFC下則margin不會重疊
資料
- 理解CSS中BFC
- http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html
- 規(guī)范
- http://www.itdecent.cn/p/0fb2f90418c3
IFC
名詞解釋

-
inline-element:以下'display'為'inline','inline-table'和'inline-block'的元素時內(nèi)聯(lián)級元素 -
inline-level box:內(nèi)聯(lián)級元素生成行級盒 -
inline box: 參與包含他的IFC的inline-level是inline-box,所有display:inline的非替換元素時inline box -
atomic inline-level boxes:不參與IFC的inline box,同時這些元素必須是非替換元素或者display:inline-block|inline-table -
anonymous inline boxes: 直接包含在塊級盒的文本 -
line box: 由IFC產(chǎn)生的盒,用于表示一行。在塊盒里面,行盒從塊盒一邊排版到另一邊。 當(dāng)有浮動時, 行盒從左浮動的最右邊排版到右浮動的最左邊。

布局規(guī)則
IFC是布局特性,并不是實際存在于Dom中的東西(即別想看見他)
IFC由不包含塊級盒的塊容器盒建立(塊容器盒中只有內(nèi)聯(lián)級盒子)
內(nèi)聯(lián)元素(inline-elemet)很容易理解(display:inline),它能生成inline-level boxes,但只有在IFC內(nèi)的才稱之為inline box
一句話很難說清楚IFC,他是布局特性,那么就應(yīng)該了解該布局特性的規(guī)則
- 在IFC中,內(nèi)聯(lián)元素在水平方向上一個接一個的排布
- line box的寬度由該盒子包含的塊填充同時會受浮動(float:left|right)塊影響。行盒的高度由行盒內(nèi)最高的inline boxes決定
- 在IFC中, 內(nèi)聯(lián)元素排列方式可以是基于頂部,底部,baseline
- 當(dāng)內(nèi)部的容器盒子太多了一個line box裝不下來,他們折行之后會變成兩個或者多個line box, line box們垂直方向無間隔地堆疊,但不能重疊
- 被分裂的inline box的分裂處的margins, borders 和 padding不會有任何視覺效果
解釋
<iframe width="100%" height="300" src="http://jsrun.net/RjYKp/embedded/all/light/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
其他
目前還不知道如何演示規(guī)則line box的寬度由該盒子包含的塊填充同時會受浮動(float:left|right)塊影響。
但我從這里偷來的圖能很好的描述這個規(guī)則

如圖,float元素不再屬于line box,他處于包裹line box的容器和line box之間,但是它的存在擠壓line box,這就是float元素能做到文字環(huán)繞的原因
資料
- https://juejin.im/entry/5938daf7a0bb9f006b2295db
- https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Visual_formatting_model#.E8.A1.8C.E5.86.85.E7.BA.A7.E5.85.83.E7.B4.A0.E4.B8.8E.E8.A1.8C.E5.86.85.E7.9B.92(Inline-level_elements_and_inline_boxes)
- http://www.zhangxinxu.com/wordpress/2010/01/css-float%E6%B5%AE%E5%8A%A8%E7%9A%84%E6%B7%B1%E5%85%A5%E7%A0%94%E7%A9%B6%E3%80%81%E8%AF%A6%E8%A7%A3%E5%8F%8A%E6%8B%93%E5%B1%95%E4%B8%80/
后記
簡書發(fā)的第一篇,本文摘抄至各個文檔博客,鏈接都已給出。
使用JSRun演示,但是簡書不能顯示,差評,再見。