BFC是什么
BFC全稱(chēng)是Block Formatting Context坠非,即塊格式化上下文。它是CSS2.1規(guī)范定義的哭尝,關(guān)于CSS渲染定位的一個(gè)概念驹吮。
視覺(jué)格式化模型
視覺(jué)格式化模型(visual formatting model)是用來(lái)處理文檔并將它顯示在視覺(jué)媒體上的機(jī)制,它也是CSS中的一個(gè)概念贡定。
視覺(jué)格式化模型定義了盒(Box)的生成赋访,盒主要包括了塊盒、行內(nèi)盒、匿名盒(沒(méi)有名字不能被選擇器選中的盒)以及一些實(shí)驗(yàn)性的盒(未來(lái)可能添加到規(guī)范中)蚓耽。盒的類(lèi)型由display
屬性決定渠牲。
塊盒(block box)
- 當(dāng)元素的CSS屬性
display
為block
,list-item
或table
時(shí)步悠,它是塊級(jí)元素 block-level嘱兼; - 視覺(jué)上呈現(xiàn)為塊,豎直排列贤徒;
- 塊級(jí)盒參與(塊格式化上下文)芹壕;
- 每個(gè)塊級(jí)元素至少生成一個(gè)塊級(jí)盒,稱(chēng)為主要塊級(jí)盒(principal block-level box)接奈。一些元素踢涌,比如
<li>
,生成額外的盒來(lái)放置項(xiàng)目符號(hào)序宦,不過(guò)多數(shù)元素只生成一個(gè)主要塊級(jí)盒睁壁。
行內(nèi)盒(inline box)
當(dāng)元素的CSS屬性
display
的計(jì)算值為inline
,inline-block
或inline-table
時(shí)互捌,稱(chēng)它為行內(nèi)級(jí)元素潘明;視覺(jué)上它將內(nèi)容與其它行內(nèi)級(jí)元素排列為多行;典型的如段落內(nèi)容秕噪,有文本(可以有多種格式譬如著重)钳降,或圖片,都是行內(nèi)級(jí)元素腌巾;
行內(nèi)級(jí)元素生成行內(nèi)級(jí)盒(inline-level boxes)遂填,參與行內(nèi)格式化上下文(inline formatting context)。同時(shí)參與生成行內(nèi)格式化上下文的行內(nèi)級(jí)盒稱(chēng)為行內(nèi)盒(inline boxes)澈蝙。所有
display:inline
的非替換元素生成的盒是行內(nèi)盒吓坚;-
不參與生成行內(nèi)格式化上下文的行內(nèi)級(jí)盒稱(chēng)為原子行內(nèi)級(jí)盒(atomic inline-level boxes)。這些盒由可替換行內(nèi)元素灯荧,或
display
值為inline-block
或inline-table
的元素生成礁击,不能拆分成多個(gè)盒;置換元素(replaced element)
一個(gè)內(nèi)容不受CSS視覺(jué)格式化模型控制逗载,CSS渲染模型并不考慮對(duì)此內(nèi)容的渲染哆窿,且元素本身一般擁有固有尺寸(寬度,高度撕贞,寬高比)的元素更耻,被稱(chēng)之為置換元素。這類(lèi)元素捏膨,瀏覽器根據(jù)元素的標(biāo)簽和屬性秧均,來(lái)決定元素的具體顯示內(nèi)容食侮。
常見(jiàn)的置換元素有這些:img,input,textarea,select,button
等除置換元素之外,所有的元素都是非置換元素目胡。
匿名盒(anonymous box)xj
匿名盒又分匿名塊盒與匿名行內(nèi)盒锯七,因?yàn)槟涿袥](méi)有名字,不能利用選擇器來(lái)選擇它們誉己,所以它們的所有屬性都為inherit
或初始默認(rèn)值眉尸;
三個(gè)定位方案
在定位的時(shí)候,瀏覽器就會(huì)根據(jù)元素的盒類(lèi)型和上下文對(duì)這些元素進(jìn)行定位巨双,可以說(shuō)盒就是定位的基本單位噪猾。定位時(shí),有三種定位方案筑累,分別是常規(guī)流袱蜡,浮動(dòng)以及絕對(duì)定位。
常規(guī)流(Normal flow)
- 在常規(guī)流中慢宗,盒一個(gè)接著一個(gè)排列;
- 在塊級(jí)格式化上下文里面坪蚁, 它們豎著排列;
- 在行內(nèi)格式化上下文里面镜沽, 它們橫著排列;
- 當(dāng)
position
為static
或relative
敏晤,并且float
為none
時(shí)會(huì)觸發(fā)常規(guī)流; - 對(duì)于靜態(tài)定位(static positioning)缅茉,
position: static
嘴脾,盒的位置是常規(guī)流布局里的位置; - 對(duì)于相對(duì)定位(relative positioning)宾舅,
position: relative
统阿,盒偏移位置由這些屬性定義top
,bottom
筹我,left
andright
。即使有偏移帆离,仍然保留原有的位置蔬蕊,其它常規(guī)流不能占用這個(gè)位置。
浮動(dòng)(Floats)
- 盒稱(chēng)為浮動(dòng)盒(floating boxes)哥谷;
- 它位于當(dāng)前行的開(kāi)頭或末尾岸夯;
- 這導(dǎo)致常規(guī)流環(huán)繞在它的周邊,除非設(shè)置 clear 屬性们妥;
絕對(duì)定位(Absolute positioning)
- 絕對(duì)定位方案猜扮,盒從常規(guī)流中被移除,不影響常規(guī)流的布局监婶;
- 它的定位相對(duì)于它的包含塊旅赢,相關(guān)CSS屬性:
top
齿桃,bottom
,left
及right
煮盼; - 如果元素的屬性
position
為absolute
或fixed
短纵,它是絕對(duì)定位元素; - 對(duì)于
position: absolute
僵控,元素定位將相對(duì)于最近的一個(gè)relative
香到、fixed
或absolute
的父元素,如果沒(méi)有則相對(duì)于body
报破;
外邊距疊加(margin collapse)
兩個(gè)或多個(gè)毗鄰的普通流中的盒子(可能是父子元素悠就,也可能是兄弟元素)在垂直方向上的外邊距會(huì)發(fā)生疊加,這種形成的外邊距稱(chēng)之為外邊距疊加充易。注意浮動(dòng)元素和絕對(duì)定位元素的外邊距不會(huì)折疊梗脾。
產(chǎn)生外邊距折疊的場(chǎng)景:
-
相鄰元素之間
毗鄰的兩個(gè)元素之間的外邊距會(huì)折疊(除非后一個(gè)元素需要清除之前的浮動(dòng))。
父元素與其第一個(gè)或最后一個(gè)子元素之間
空的塊級(jí)元素
一些需要注意的地方:
- 上述情況的組合會(huì)產(chǎn)生更復(fù)雜的外邊距折疊蔽氨。
- 即使某一外邊距為0藐唠,這些規(guī)則仍然適用。因此就算父元素的外邊距是0鹉究,第一個(gè)或最后一個(gè)子元素的外邊距仍然會(huì)“溢出”到父元素的外面宇立。
- 如果參與折疊的外邊距中包含負(fù)值,折疊后的外邊距的值為最大的正邊距與最小的負(fù)邊距(即絕對(duì)值最大的負(fù)邊距)的和自赔。
- 如果所有參與折疊的外邊距都為負(fù)妈嘹,折疊后的外邊距的值為最小的負(fù)邊距的值。這一規(guī)則適用于相鄰元素和嵌套元素绍妨。
塊格式化上下文
塊格式上下文是頁(yè)面CSS 視覺(jué)渲染的一部分润脸,用于決定塊盒子的布局及浮動(dòng)相互影響范圍的一個(gè)區(qū)域。
BFC的觸發(fā)方法:
- 根元素或其它包含它的元素他去;
- 浮動(dòng) (元素的float不為none)毙驯;
- 絕對(duì)定位元素 (元素的position為absolute或fixed);
- 行內(nèi)塊inline-blocks(元素的 display: inline-block)灾测;
- 表格單元格(元素的display: table-cell爆价,HTML表格單元格默認(rèn)屬性);
- overflow的值不為visible的元素媳搪;
- 彈性盒 flex boxes (元素的display: flex或inline-flex)铭段;
但其中,最常見(jiàn)的就是overflow:hidden
秦爆、float:left/right
序愚、position:absolute
。也就是說(shuō)等限,每次看到這些屬性的時(shí)候爸吮,就代表了該元素觸發(fā)了一個(gè)BFC了芬膝。
BFC的范圍
BFC包含創(chuàng)建該上下文元素的所有子元素,但不包括創(chuàng)建了新BFC的子元素的內(nèi)部元素拗胜。
BFC的布局規(guī)矩
內(nèi)部的盒會(huì)在垂直方向一個(gè)接一個(gè)排列(可以看作BFC中有一個(gè)的常規(guī)流)蔗候;
處于同一個(gè)BFC中的元素相互影響,可能會(huì)發(fā)生margin collapse埂软;
每個(gè)元素的margin box的左邊锈遥,與容器塊border box的左邊相接觸(對(duì)于從左往右的格式化,否則相反)勘畔。即使存在浮動(dòng)也是如此所灸;
BFC就是頁(yè)面上的一個(gè)隔離的獨(dú)立容器,容器里面的子元素不會(huì)影響到外面的元素炫七,反之亦然爬立;
計(jì)算BFC的高度時(shí),考慮BFC所包含的所有元素万哪,浮動(dòng)元素也參與計(jì)算侠驯;
-
浮動(dòng)盒區(qū)域不疊加到BFC上;
浮動(dòng)定位和清除浮動(dòng)時(shí)只會(huì)應(yīng)用于同一個(gè)BFC內(nèi)的元素奕巍。浮動(dòng)不會(huì)影響其它BFC中元素的布局吟策,而清除浮動(dòng)只能清除同一BFC中在它前面的元素的浮動(dòng)。外邊距折疊也只會(huì)發(fā)生在屬于同一BFC的塊級(jí)元素之間的止。
BFC用途
- 清除浮動(dòng)
- 防止垂直margin合并
- 布局:自適應(yīng)兩欄布局
IFC
Inline Formatting Contexts檩坚,也就是“內(nèi)聯(lián)格式化上下文”。
觸發(fā)條件
- 塊級(jí)元素中僅包含內(nèi)聯(lián)級(jí)別元素
IFC布局規(guī)則
- IFC中的line box一般左右都貼緊整個(gè)IFC诅福,但是會(huì)因?yàn)閒loat元素而擾亂匾委。float元素會(huì)位于IFC與與line box之間,使得line box寬度縮短氓润。
- IFC中時(shí)不可能有塊級(jí)元素的赂乐,當(dāng)插入塊級(jí)元素時(shí)(如p中插入div)會(huì)產(chǎn)生兩個(gè)匿名塊與div分隔開(kāi),即產(chǎn)生兩個(gè)IFC咖气,每個(gè)IFC對(duì)外表現(xiàn)為塊級(jí)元素沪猴,與div垂直排列。
IFC用途
- 水平居中:當(dāng)一個(gè)塊要在環(huán)境中水平居中時(shí)采章,設(shè)置其為inline-block則會(huì)在外層產(chǎn)生IFC,通過(guò)text-align則可以使其水平居中壶辜。
- 垂直居中:創(chuàng)建一個(gè)IFC悯舟,用其中一個(gè)元素?fù)伍_(kāi)父元素的高度,然后設(shè)置其vertical-align:middle砸民,其他行內(nèi)元素則可以在此父元素下垂直居中抵怎。