BFC是什么
BFC全稱是Block Formatting Context,即塊格式化上下文。它是CSS2.1規(guī)范定義的,關于CSS渲染定位的一個概念。
視覺格式化模型
視覺格式化模型(visual formatting model)是用來處理文檔并將它顯示在視覺媒體上的機制,它也是CSS中的一個概念。
視覺格式化模型定義了盒(Box)的生成,盒主要包括了塊盒、行內盒、匿名盒(沒有名字不能被選擇器選中的盒)以及一些實驗性的盒(未來可能添加到規(guī)范中)。盒的類型由display屬性決定。
塊盒(block box)
- 當元素的CSS屬性
display為block,list-item或table時,它是塊級元素 block-level; - 視覺上呈現為塊,豎直排列;
- 塊級盒參與(塊格式化上下文);
- 每個塊級元素至少生成一個塊級盒,稱為主要塊級盒(principal block-level box)。一些元素,比如
<li>,生成額外的盒來放置項目符號,不過多數元素只生成一個主要塊級盒。
行內盒(inline box)
當元素的CSS屬性
display的計算值為inline,inline-block或inline-table時,稱它為行內級元素;視覺上它將內容與其它行內級元素排列為多行;典型的如段落內容,有文本(可以有多種格式譬如著重),或圖片,都是行內級元素;
行內級元素生成行內級盒(inline-level boxes),參與行內格式化上下文(inline formatting context)。同時參與生成行內格式化上下文的行內級盒稱為行內盒(inline boxes)。所有
display:inline的非替換元素生成的盒是行內盒;-
不參與生成行內格式化上下文的行內級盒稱為原子行內級盒(atomic inline-level boxes)。這些盒由可替換行內元素,或
display值為inline-block或inline-table的元素生成,不能拆分成多個盒;置換元素(replaced element)
一個內容不受CSS視覺格式化模型控制,CSS渲染模型并不考慮對此內容的渲染,且元素本身一般擁有固有尺寸(寬度,高度,寬高比)的元素,被稱之為置換元素。這類元素,瀏覽器根據元素的標簽和屬性,來決定元素的具體顯示內容。
常見的置換元素有這些:img,input,textarea,select,button等除置換元素之外,所有的元素都是非置換元素。
匿名盒(anonymous box)xj
匿名盒又分匿名塊盒與匿名行內盒,因為匿名盒沒有名字,不能利用選擇器來選擇它們,所以它們的所有屬性都為inherit或初始默認值;
三個定位方案
在定位的時候,瀏覽器就會根據元素的盒類型和上下文對這些元素進行定位,可以說盒就是定位的基本單位。定位時,有三種定位方案,分別是常規(guī)流,浮動以及絕對定位。
常規(guī)流(Normal flow)
- 在常規(guī)流中,盒一個接著一個排列;
- 在塊級格式化上下文里面, 它們豎著排列;
- 在行內格式化上下文里面, 它們橫著排列;
- 當
position為static或relative,并且float為none時會觸發(fā)常規(guī)流; - 對于靜態(tài)定位(static positioning),
position: static,盒的位置是常規(guī)流布局里的位置; - 對于相對定位(relative positioning),
position: relative,盒偏移位置由這些屬性定義top,bottom,leftandright。即使有偏移,仍然保留原有的位置,其它常規(guī)流不能占用這個位置。
浮動(Floats)
- 盒稱為浮動盒(floating boxes);
- 它位于當前行的開頭或末尾;
- 這導致常規(guī)流環(huán)繞在它的周邊,除非設置 clear 屬性;
絕對定位(Absolute positioning)
- 絕對定位方案,盒從常規(guī)流中被移除,不影響常規(guī)流的布局;
- 它的定位相對于它的包含塊,相關CSS屬性:
top,bottom,left及right; - 如果元素的屬性
position為absolute或fixed,它是絕對定位元素; - 對于
position: absolute,元素定位將相對于最近的一個relative、fixed或absolute的父元素,如果沒有則相對于body;
外邊距疊加(margin collapse)
兩個或多個毗鄰的普通流中的盒子(可能是父子元素,也可能是兄弟元素)在垂直方向上的外邊距會發(fā)生疊加,這種形成的外邊距稱之為外邊距疊加。注意浮動元素和絕對定位元素的外邊距不會折疊。
產生外邊距折疊的場景:
-
相鄰元素之間
毗鄰的兩個元素之間的外邊距會折疊(除非后一個元素需要清除之前的浮動)。
父元素與其第一個或最后一個子元素之間
空的塊級元素
一些需要注意的地方:
- 上述情況的組合會產生更復雜的外邊距折疊。
- 即使某一外邊距為0,這些規(guī)則仍然適用。因此就算父元素的外邊距是0,第一個或最后一個子元素的外邊距仍然會“溢出”到父元素的外面。
- 如果參與折疊的外邊距中包含負值,折疊后的外邊距的值為最大的正邊距與最小的負邊距(即絕對值最大的負邊距)的和。
- 如果所有參與折疊的外邊距都為負,折疊后的外邊距的值為最小的負邊距的值。這一規(guī)則適用于相鄰元素和嵌套元素。
塊格式化上下文
塊格式上下文是頁面CSS 視覺渲染的一部分,用于決定塊盒子的布局及浮動相互影響范圍的一個區(qū)域。
BFC的觸發(fā)方法:
- 根元素或其它包含它的元素;
- 浮動 (元素的float不為none);
- 絕對定位元素 (元素的position為absolute或fixed);
- 行內塊inline-blocks(元素的 display: inline-block);
- 表格單元格(元素的display: table-cell,HTML表格單元格默認屬性);
- overflow的值不為visible的元素;
- 彈性盒 flex boxes (元素的display: flex或inline-flex);
但其中,最常見的就是overflow:hidden、float:left/right、position:absolute。也就是說,每次看到這些屬性的時候,就代表了該元素觸發(fā)了一個BFC了。
BFC的范圍
BFC包含創(chuàng)建該上下文元素的所有子元素,但不包括創(chuàng)建了新BFC的子元素的內部元素。
BFC的布局規(guī)矩
內部的盒會在垂直方向一個接一個排列(可以看作BFC中有一個的常規(guī)流);
處于同一個BFC中的元素相互影響,可能會發(fā)生margin collapse;
每個元素的margin box的左邊,與容器塊border box的左邊相接觸(對于從左往右的格式化,否則相反)。即使存在浮動也是如此;
BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素,反之亦然;
計算BFC的高度時,考慮BFC所包含的所有元素,浮動元素也參與計算;
-
浮動盒區(qū)域不疊加到BFC上;
浮動定位和清除浮動時只會應用于同一個BFC內的元素。浮動不會影響其它BFC中元素的布局,而清除浮動只能清除同一BFC中在它前面的元素的浮動。外邊距折疊也只會發(fā)生在屬于同一BFC的塊級元素之間。
BFC用途
- 清除浮動
- 防止垂直margin合并
- 布局:自適應兩欄布局
IFC
Inline Formatting Contexts,也就是“內聯格式化上下文”。
觸發(fā)條件
- 塊級元素中僅包含內聯級別元素
IFC布局規(guī)則
- IFC中的line box一般左右都貼緊整個IFC,但是會因為float元素而擾亂。float元素會位于IFC與與line box之間,使得line box寬度縮短。
- IFC中時不可能有塊級元素的,當插入塊級元素時(如p中插入div)會產生兩個匿名塊與div分隔開,即產生兩個IFC,每個IFC對外表現為塊級元素,與div垂直排列。
IFC用途
- 水平居中:當一個塊要在環(huán)境中水平居中時,設置其為inline-block則會在外層產生IFC,通過text-align則可以使其水平居中。
- 垂直居中:創(chuàng)建一個IFC,用其中一個元素撐開父元素的高度,然后設置其vertical-align:middle,其他行內元素則可以在此父元素下垂直居中。