全國(guó)咨詢(xún)/投訴熱線:400-618-4000

首頁(yè)技術(shù)文章正文

前端BFC是什么?【web前端培訓(xùn)】

更新時(shí)間:2020-10-16 來(lái)源:黑馬程序員 瀏覽量:

1. 引言

在前端的布局手段中,一直有這么一個(gè)知識(shí)點(diǎn),很多前端開(kāi)發(fā)者都知道有它的存在,但是很多人也僅僅是知道它的存在而已,對(duì)它的作用也只是將將說(shuō)得出來(lái),可是卻沒(méi)辦法說(shuō)得非常的清晰。這個(gè)知識(shí)點(diǎn),就是BFC。想要了解BFC的規(guī)則,前提必須是熟悉前端網(wǎng)頁(yè)的多種布局手段,例如盒的顯示模式display,三種布局手段標(biāo)準(zhǔn)流(normal)、浮動(dòng)流(float)、定位流(position)等。你只有熟練掌握了這些布局手段之后,才能很好的理解BFC。今天這篇文章,來(lái)大家解析一下BFC,希望對(duì)各位新老朋友有所幫助。

2. 定義

BFC - Block Formatting Context 塊級(jí)格式化上下文 BFC的定義,在官方文檔到中,是這么介紹BFC的。

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.

強(qiáng)行翻譯一下吧,簡(jiǎn)單來(lái)說(shuō),這句話的意思就是:

一個(gè)BFC區(qū)域包含創(chuàng)建該上下文元素的所有子元素,但是不包括創(chuàng)建了新的BFC的子元素的內(nèi)部元素

很顯然,哪怕強(qiáng)行翻譯了,大部分人依舊是看不懂這句話的??炊伎床欢?,那自然就沒(méi)什么能把它說(shuō)明白。talk is cheap, show me the code.看不懂意思,我用代碼來(lái)給你演示。


<div class="box1" id="HM_bfc1">
    <div class="box2">div>
    <div class="box3">div>
    <div class="box4">div>
    <div class="box5" id="HM_bfc2">
        <div class="box6">div>
        <div class="box7">div>
        <div class="box8">div>
    div>
div>

用這段代碼來(lái)解釋上面那段BFC定義的話,就應(yīng)該是這個(gè)意思:#HM_bfc1是一塊BFC區(qū)域,這塊區(qū)域包含了box2、box3、box4、box5,也就是所有#HM_bfc1的子元素。同時(shí)#HM_bfc2也創(chuàng)造了一塊BFC區(qū)域,包含了box6,box7,box8。注意,第一個(gè)box1的BFC,只包括box1的子元素box2345,不包括box678。#HM_bfc2這個(gè)BFC同樣也僅僅是包括自己的子元素box678。

劃重點(diǎn)

每一個(gè)BFC區(qū)域只包括其子元素,不包括其子元素的子元素。(這1點(diǎn)比較容易理解)

每一個(gè)BFC區(qū)域都是獨(dú)立隔絕的,互不影響!(這點(diǎn)不太好理解,但是后續(xù)會(huì)使用代碼驗(yàn)證)

看完上面的描述,很多朋友依舊不懂,把第2節(jié)用心的再讀一遍,相信你會(huì)有新的收獲。然后往下繼續(xù)閱讀,你會(huì)豁然開(kāi)朗。

3. 觸發(fā)BFC

并不是任意一個(gè)元素都可以被當(dāng)做BFC,只有當(dāng)這個(gè)元素滿(mǎn)足以下任意一個(gè)條件的時(shí)候,這個(gè)元素才會(huì)被當(dāng)做一個(gè)BFC。

觸發(fā)BFC的條件

·body根元素

·設(shè)置浮動(dòng),不包括none

·設(shè)置定位,absoulte或者fixed

·行內(nèi)塊顯示模式,inline-block

·設(shè)置overflow,即hidden,auto,scroll

·表格單元格,table-cell

·彈性布局,flex

上代碼說(shuō)明

BFC01

首先, body元素是1個(gè)BFC,因?yàn)樗鼭M(mǎn)足我們的第1個(gè)條件(body根元素),這個(gè)BFC區(qū)域包含子元素hm1234,但是不包括兩個(gè)p標(biāo)簽,需要注意的是,hm3不是一個(gè)BFC區(qū)域,因?yàn)樗粷M(mǎn)足上面任意1個(gè)條件。如果我們希望hm3也是1個(gè)BFC區(qū)域,只要讓hm3滿(mǎn)足上面任意一個(gè)條件即可。

BFC02


這個(gè)時(shí)候,hm3元素被設(shè)置為了overflow為hidden,滿(mǎn)足上面第5個(gè)條件,所以此時(shí),hm3就成為了一個(gè)BFC區(qū)域,這個(gè)BFC區(qū)域包含其所有子元素 – 兩個(gè)p標(biāo)簽。

劃重點(diǎn):

并不是所有的元素都是BFC, 只有滿(mǎn)足了上面的任意1個(gè)條件之后,這個(gè)元素才成為1個(gè)BFC。

一個(gè)BFC區(qū)域,只包含其所有子元素,不包含子元素的子元素。

4. 利用BFC解決問(wèn)題

在你明白了解BFC的觸發(fā)規(guī)則之后,那么就需要利用BFC的特點(diǎn)來(lái)解決我們?cè)诓季种杏龅降囊恍﹩?wèn)題了,還記得我們之前說(shuō)過(guò),BFC有一個(gè)特點(diǎn)是:每一個(gè)BFC區(qū)域都是相互獨(dú)立,互不影響的。


4.1 解決外邊距的塌陷問(wèn)題(垂直塌陷)

開(kāi)發(fā)中,前端的布局手段,離不開(kāi)外邊距margin,那么,也會(huì)遇到一些問(wèn)題,例如外邊距的垂直塌陷問(wèn)題。

BFC03


通過(guò)以上的實(shí)例,我們會(huì)發(fā)現(xiàn),代碼給兩個(gè)div盒子,都添加了四個(gè)方向的margin,講道理,學(xué)過(guò)數(shù)學(xué)的都知道,100+100=200.可是,盒子之間的距離,現(xiàn)在卻之后100px。這就是很典型的margin的塌陷,兩段margin重疊到了一塊,互相影響。那么,如何利用BFC,讓這個(gè)問(wèn)題得到解決呢?;貞浵?,上文說(shuō)過(guò),BFC,就是一個(gè)與世隔絕的獨(dú)立區(qū)域,不會(huì)互相影響,那么,我們可以將這兩個(gè)盒子,放到兩個(gè)BFC區(qū)域中,即可解決這個(gè)問(wèn)題。

BFC04


4.2 利用BFC解決包含塌陷

當(dāng)父子關(guān)系的盒子,給子元素添加margin-top,有可能會(huì)把父元素一起帶跑。

BFC05

原本,正確的顯示方式,應(yīng)該是粉色盒子與紅色盒子的頂部距離為50px,但是由于margin的塌陷問(wèn)題,導(dǎo)致盒子內(nèi)部的布局影響到了外部。這個(gè)時(shí)候,就可以觸發(fā)BFC,將父盒子變成一個(gè)獨(dú)立的區(qū)域,這樣在BFC區(qū)域內(nèi)部的任何操作,都不會(huì)影響到外部。

BFC06


4.3 當(dāng)浮動(dòng)產(chǎn)生影響的時(shí)候,可以利用BFC來(lái)清除浮動(dòng)的影響

BFC07


以上代碼表示,一個(gè)沒(méi)有設(shè)置高度的父盒子,包含著七個(gè)子元素。如果此時(shí),所有的子元素都浮動(dòng)的話。

BFC08


當(dāng)所有的子元素都浮動(dòng)了,這個(gè)時(shí)候,父盒子失去了原有的高度,這就是浮動(dòng)的影響。這個(gè)時(shí)候,同樣也可用BFC的機(jī)制,來(lái)清除浮動(dòng)帶來(lái)的影響。使用BFC,將所有的浮動(dòng)元素包裹起來(lái)。

BFC09

4.4 BFC可以阻止標(biāo)準(zhǔn)流元素被浮動(dòng)元素覆蓋

BFC10

以上情況,紅色盒子浮動(dòng),藍(lán)色盒子時(shí)標(biāo)準(zhǔn)流,默認(rèn)情況下,浮動(dòng)元素覆蓋了標(biāo)準(zhǔn)流元素。但是,如果將藍(lán)色盒子的BFC觸發(fā),那么情況將有所變化。

BFC10

當(dāng)藍(lán)色盒子觸發(fā)了BFC之后,浮動(dòng)元素再也不能覆蓋它了,而且還能利用這個(gè)特性,來(lái)實(shí)現(xiàn)藍(lán)色盒子寬度根據(jù)紅色盒子的寬度來(lái)做自動(dòng)適應(yīng)


5.總結(jié)

一個(gè)BFC區(qū)域只包含其子元素,不包括其子元素的子元素。

并不是所有的元素都能成為一塊BFC區(qū)域,只有當(dāng)這個(gè)元素滿(mǎn)足條件的時(shí)候才會(huì)成為一塊BFC區(qū)域。

不同的BFC區(qū)域之間是相互獨(dú)立的,互不影響的。利用這個(gè)特性我們可以讓不同BFC區(qū)域之間的布局不產(chǎn)生影響。


猜你喜歡:

JS實(shí)現(xiàn)深度拷貝的方法?

什么是自適應(yīng)式頁(yè)面?

好用的前端開(kāi)發(fā)工具:這四款你必須知道!

前端開(kāi)發(fā)培訓(xùn)課程

分享到:
在線咨詢(xún) 我要報(bào)名
和我們?cè)诰€交談!