學(xué)習(xí)塊格式化上下文(BlockFormattingContext)

什么是BFC

BFC全稱(chēng)是Block Formatting Context惦费,即塊格式化上下文舔清。它是CSS2.1規(guī)范定義的育八,關(guān)于CSS渲染定位的一個(gè)概念。要明白BFC到底是什么斯够,首先來(lái)看看什么是視覺(jué)格式化模型。

視覺(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è)盒骑歹;

匿名盒(anonymous box)

匿名盒也有份匿名塊盒與匿名行內(nèi)盒预烙,因?yàn)槟涿袥](méi)有名字,不能利用選擇器來(lái)選擇它們道媚,所以它們的所有屬性都為inherit或初始默認(rèn)值扁掸;

如下面例子,會(huì)創(chuàng)鍵匿名塊盒來(lái)包含毗鄰的行內(nèi)級(jí)盒:

<div>
    Some inline text
    <p>followed by a paragraph</p>
    followed by more inline text.
</div>
image.png

三個(gè)定位方案

在定位的時(shí)候最域,瀏覽器就會(huì)根據(jù)元素的盒類(lèi)型和上下文對(duì)這些元素進(jìn)行定位谴分,可以說(shuō)盒就是定位的基本單位。定位時(shí)镀脂,有三種定位方案牺蹄,分別是常規(guī)流,浮動(dòng)已經(jīng)絕對(duì)定位薄翅。

常規(guī)流(Normal flow)

  1. 在常規(guī)流中沙兰,盒一個(gè)接著一個(gè)排列;
  2. 在塊級(jí)格式化上下文里面氓奈, 它們豎著排列;
  3. 在行內(nèi)格式化上下文里面鼎天, 它們橫著排列;
  4. 當(dāng)position為static或relative舀奶,并且float為none時(shí)會(huì)觸發(fā)常規(guī)流;
  5. 對(duì)于靜態(tài)定位(static positioning)斋射,position: static育勺,盒的位置是常規(guī)流布局里的位置;
  6. 對(duì)于相對(duì)定位(relative positioning)罗岖,position: relative涧至,盒偏移位置由這些屬性定義top,bottom桑包,leftandright南蓬。即使有偏移,仍然保留原有的位置捡多,其它常規(guī)流不能占用這個(gè)位置蓖康。

浮動(dòng)(Floats)

  1. 盒稱(chēng)為浮動(dòng)盒(floating boxes);
  2. 它位于當(dāng)前行的開(kāi)頭或末尾垒手;
  3. 這導(dǎo)致常規(guī)流環(huán)繞在它的周邊,除非設(shè)置 clear 屬性倒信;

絕對(duì)定位(Absolute positioning)

  1. 絕對(duì)定位方案科贬,盒從常規(guī)流中被移除,不影響常規(guī)流的布局鳖悠;
  2. 它的定位相對(duì)于它的包含塊榜掌,相關(guān)CSS屬性:top,bottom乘综,left及right憎账;
  3. 如果元素的屬性position為absolute或fixed,它是絕對(duì)定位元素卡辰;
  4. 對(duì)于position: absolute胞皱,元素定位將相對(duì)于最近的一個(gè)relative、fixed或absolute的父元素九妈,如果沒(méi)有則相對(duì)于body反砌;

塊格式化上下文

到這里,已經(jīng)對(duì)CSS的定位有一定的了解了萌朱,從上面的信息中也可以得知宴树,塊格式上下文是頁(yè)面CSS 視覺(jué)渲染的一部分,用于決定塊盒子的布局及浮動(dòng)相互影響范圍的一個(gè)區(qū)域晶疼。

BFC的創(chuàng)建方法

  • 根元素或其它包含它的元素酒贬;
  • 浮動(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í)候夺衍,就代表了該元素以及創(chuàng)建了一個(gè)BFC了。

BFC的范圍

BFC的范圍在MDN中是這樣描述的喜命。

A block formatting context contains everything inside of the element creating it that is not also inside a descendant element that creates a new block formatting context.

中文的意思一個(gè)BFC包含創(chuàng)建該上下文元素的所有子元素沟沙,但不包括創(chuàng)建了新BFC的子元素的內(nèi)部元素。

這段看上去有點(diǎn)奇怪壁榕,我是這么理解的矛紫,加入有下面代碼,class名為.BFC代表創(chuàng)建了新的塊格式化:

<div id='div_1' class='BFC'>
    <div id='div_2'>
        <div id='div_3'></div>
        <div id='div_4'></div>
    </div>
    <div id='div_5' class='BFC'>
        <div id='div_6'></div>
        <div id='div_7'></div>
    </div>
</div>

這段代碼表示牌里,#div_1創(chuàng)建了一個(gè)塊格式上下文颊咬,這個(gè)上下文包括了#div_2、#div_3牡辽、#div_4喳篇、#div_5。即#div_2中的子元素也屬于#div_1所創(chuàng)建的BFC态辛。但由于#div_5創(chuàng)建了新的BFC麸澜,所以#div_6和#div_7就被排除在外層的BFC之外。

我認(rèn)為奏黑,這從另一方角度說(shuō)明炊邦,一個(gè)元素不能同時(shí)存在于兩個(gè)BFC中。

BFC的一個(gè)最重要的效果是攀涵,讓處于BFC內(nèi)部的元素與外部的元素相互隔離铣耘,使內(nèi)外元素的定位不會(huì)相互影響。這是利用BFC清除浮動(dòng)所利用的特性以故,關(guān)于清除浮動(dòng)將在后面講述蜗细。

如果一個(gè)元素能夠同時(shí)處于兩個(gè)BFC中,那么就意味著這個(gè)元素能與兩個(gè)BFC中的元素發(fā)生作用,就違反了BFC的隔離作用炉媒,所以這個(gè)假設(shè)就不成立了踪区。

BFC的效果

就如剛才提到的,BFC的最顯著的效果就是建立一個(gè)隔離的空間吊骤,斷絕空間內(nèi)外元素間相互的作用缎岗。然而,BFC還有更多的特性:

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.

In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box's line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).

簡(jiǎn)單歸納一下:

  1. 內(nèi)部的盒會(huì)在垂直方向一個(gè)接一個(gè)排列(可以看作BFC中有一個(gè)的常規(guī)流)白粉;

  2. 處于同一個(gè)BFC中的元素相互影響传泊,可能會(huì)發(fā)生margin collapse;

  3. 每個(gè)元素的margin box的左邊鸭巴,與容器塊border box的左邊相接觸(對(duì)于從左往右的格式化眷细,否則相反)。即使存在浮動(dòng)也是如此鹃祖;

  4. BFC就是頁(yè)面上的一個(gè)隔離的獨(dú)立容器溪椎,容器里面的子元素不會(huì)影響到外面的元素,反之亦然恬口;

  5. 計(jì)算BFC的高度時(shí)校读,考慮BFC所包含的所有元素,連浮動(dòng)元素也參與計(jì)算祖能;

  6. 浮動(dòng)盒區(qū)域不疊加到BFC上歉秫;

這么多性質(zhì)有點(diǎn)難以理解,但可以作如下推理來(lái)幫助理解:html的根元素就是<html>养铸,而根元素會(huì)創(chuàng)建一個(gè)BFC端考,創(chuàng)建一個(gè)新的BFC時(shí)就相當(dāng)于在這個(gè)元素內(nèi)部創(chuàng)建一個(gè)新的<html>,子元素的定位就如同在一個(gè)新<html>頁(yè)面中那樣揭厚,而這個(gè)新舊html頁(yè)面之間時(shí)不會(huì)相互影響的。

上述這個(gè)理解并不是最準(zhǔn)確的理解扶供,甚至是將因果倒置了(因?yàn)閔tml是根元素筛圆,因此才會(huì)有BFC的特性,而不是BFC有html的特性)椿浓,但這樣的推理可以幫助理解BFC這個(gè)概念太援。

從實(shí)際代碼來(lái)分析BFC
講了這么多,還是比較難理解扳碍,所以下面通過(guò)一些例子來(lái)加深對(duì)BFC的認(rèn)識(shí)提岔。

實(shí)例一

<style>
    * {
        margin: 0;
        padding: 0;
    }
    .left{
        background: #73DE80;    /* 綠色 */
        opacity: 0.5;
        border: 3px solid #F31264;
        width: 200px;
        height: 200px;
        float: left;
    }
    .right{                     /* 粉色 */
        background: #EF5BE2;
        opacity: 0.5;
        border: 3px solid #F31264;
        width:400px;
        min-height: 100px;
    }
    .box{
        background:#888;
        height: 100%;
        margin-left: 50px;
    }
</style>
<div class='box'>
    <div class='left'> </div>
    <div class='right'> </div>
</div>

顯示效果:

綠色框('#left')向左浮動(dòng),它創(chuàng)建了一個(gè)新BFC笋敞,但暫時(shí)不討論它所創(chuàng)建的BFC碱蒙。由于綠色框浮動(dòng)了,它脫離了原本normal flow的位置,因此赛惩,粉色框('#right')就被定位到灰色父元素的左上角(特性3:元素左邊與容器左邊相接觸)哀墓,與浮動(dòng)綠色框發(fā)生了重疊。

同時(shí)喷兼,由于灰色框('#box')并沒(méi)有創(chuàng)建BFC篮绰,因此在計(jì)算高度的時(shí)候,并沒(méi)有考慮綠色框的區(qū)域(特性6:浮動(dòng)區(qū)域不疊加到BFC區(qū)域上)季惯,發(fā)生了高度坍塌吠各,這也是常見(jiàn)問(wèn)題之一。

實(shí)例二

現(xiàn)在通過(guò)設(shè)置overflow:hidden來(lái)創(chuàng)建BFC勉抓,再看看效果如何贾漏。

.BFC{
    overflow: hidden;
}

<div class='box BFC'>
    <div class='left'> </div>
    <div class='right'> </div>
</div>
image.png

灰色框創(chuàng)建了一個(gè)新的BFC后,高度發(fā)生了變化琳状,計(jì)算高度時(shí)它將綠色框區(qū)域也考慮進(jìn)去了(特性5:計(jì)算BFC的高度時(shí)磕瓷,浮動(dòng)元素也參與計(jì)算);

而綠色框和紅色框的顯示效果仍然沒(méi)有任何變化念逞。

實(shí)例三

現(xiàn)在困食,現(xiàn)將一些小塊添加到粉色框中,看看效果:

<style>
    .little{
        background: #fff;
        width: 50px;
        height: 50px;
        margin: 10px;
        float: left;
    }
</style>

<div class='box BFC'>
    <div class='left'> </div>
    <div class='right'>
        <div class='little'></div>
        <div class='little'></div>
        <div class='little'></div>
    </div>
</div>

image.png

由于粉色框沒(méi)有創(chuàng)建新的BFC翎承,因此粉色框中白色塊受到了綠色框的影響硕盹,被擠到了右邊去了。先不管這個(gè)叨咖,看看白色塊的margin瘩例。

實(shí)例四

利用同實(shí)例二中一樣的方法,為粉色框創(chuàng)建BFC:

<div class='box BFC'>
    <div class='left'> </div>
    <div class='right BFC'>
        <div class='little'></div>
        <div class='little'></div>
        <div class='little'></div>
    </div>
</div>

image.png

一旦粉色框創(chuàng)建了新的BFC以后甸各,粉色框就不與綠色浮動(dòng)框發(fā)生重疊了垛贤,同時(shí)內(nèi)部的白色塊處于隔離的空間(特性4:BFC就是頁(yè)面上的一個(gè)隔離的獨(dú)立容器),白色塊也不會(huì)受到綠色浮動(dòng)框的擠壓趣倾。

總結(jié)

以上就是BFC的分析聘惦,BFC的概念比較抽象,但通過(guò)實(shí)例分析應(yīng)該能夠更好地理解BFC儒恋。在實(shí)際中善绎,利用BFC可以閉合浮動(dòng)(實(shí)例二),防止與浮動(dòng)元素重疊(實(shí)例四)诫尽。同時(shí)禀酱,由于BFC的隔離作用,可以利用BFC包含一個(gè)元素牧嫉,防止這個(gè)元素與BFC外的元素發(fā)生margin collapse剂跟。

轉(zhuǎn)自

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子浩聋,更是在濱河造成了極大的恐慌观蜗,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衣洁,死亡現(xiàn)場(chǎng)離奇詭異墓捻,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)坊夫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門(mén)砖第,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人环凿,你說(shuō)我怎么就攤上這事梧兼。” “怎么了智听?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵羽杰,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我到推,道長(zhǎng)考赛,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任莉测,我火速辦了婚禮颜骤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘捣卤。我一直安慰自己忍抽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布董朝。 她就那樣靜靜地躺著鸠项,像睡著了一般。 火紅的嫁衣襯著肌膚如雪子姜。 梳的紋絲不亂的頭發(fā)上锈锤,一...
    開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音闲询,去河邊找鬼。 笑死浅辙,一個(gè)胖子當(dāng)著我的面吹牛扭弧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播记舆,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼鸽捻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起御蒲,我...
    開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤衣赶,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后厚满,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體府瞄,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年碘箍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了遵馆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丰榴,死狀恐怖货邓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情四濒,我是刑警寧澤换况,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站盗蟆,受9級(jí)特大地震影響戈二,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜姆涩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一挽拂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骨饿,春花似錦亏栈、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至察署,卻和暖如春闷游,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贴汪。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工脐往, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扳埂。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓业簿,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親阳懂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子梅尤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 問(wèn)答題47 /72 常見(jiàn)瀏覽器兼容性問(wèn)題與解決方案柜思? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,734評(píng)論 1 92
  • 先前在學(xué)習(xí)CSS float時(shí),有同學(xué)提到了BFC這個(gè)詞巷燥,作為求知好問(wèn)的好學(xué)生赡盘,哪里不懂查哪里,那么今天就來(lái)研究一...
    這名字真不對(duì)閱讀 6,548評(píng)論 3 19
  • 什么是BFC BFC全稱(chēng)是Block Formatting Context,即塊格式化上下文。它是CSS2.1規(guī)范...
    陌客百里閱讀 531評(píng)論 3 4
  • 轉(zhuǎn)載自(http://web.jobbole.com/83274/) BFC BFC全稱(chēng)是Block Format...
    居客俠閱讀 2,137評(píng)論 0 20
  • BFC全稱(chēng)是Block Formatting Context稽莉,即塊格式化上下文。它是CSS2.1規(guī)范定義的霉咨,關(guān)于C...
    xf0128閱讀 330評(píng)論 0 0