一掸茅、BFC
1父腕、定義:
先給一個(gè)官方的定義:(可能會(huì)看不懂我也不懂)
Formatting context(格式化上下文) 是 W3C CSS2.1規(guī)范中的一個(gè)概念弱匪。每個(gè)渲染區(qū)域用formattingContext表示,它是頁面中的一塊渲染區(qū)域璧亮,并且有一套渲染規(guī)則萧诫。它決定了其子元素將如何定位,以及和其他元素的關(guān)系和相互作用
再看下面這個(gè)定義:(一點(diǎn)點(diǎn)懂)
BFC(Block Formatting Context)枝嘶,塊級格式化上下文财搁。相當(dāng)于制定一種如BFC這樣的規(guī)則,在普通流中按照該規(guī)則進(jìn)行布局躬络。
在正常流中的盒子要么屬于塊級格式化上下文(BFC),要么屬于內(nèi)聯(lián)格式化上下文仅乓,即塊級元素在頁面渲染的時(shí)候遵循怎么樣的規(guī)則筒严,它們之間有怎么樣的作用磨取。
再看這個(gè):(還是一點(diǎn)點(diǎn)懂)
具有 BFC 特性的元素可以看作是隔離了的獨(dú)立容器,容器里面的元素不會(huì)在布局上影響到外面的元素馁菜,并且 BFC 具有普通容器所沒有的一些特性。通俗一點(diǎn)來講铃岔,可以把 BFC 理解為一個(gè)封閉的大箱子汪疮,箱子內(nèi)部的元素?zé)o論如何翻江倒海,都不會(huì)影響到外部毁习。
總結(jié):BFC沒有定義智嚷,只有功能或特性
2、BFC會(huì)在哪里產(chǎn)生(官方的)
只要元素滿足下面任一條件即可觸發(fā) BFC 特性
(1)body根元素
html里的根元素產(chǎn)生相應(yīng)的“塊級格式化上下文”這類的規(guī)則纺且,如某些規(guī)則:塊級容器可以充滿父容器盏道,父容器可以被子元素?fù)伍_,外邊距產(chǎn)生合并载碌,渲染順序是從上到下(同一個(gè)塊級格式化上下文中相鄰塊級盒之間的豎直margin會(huì)合并)
(2)浮動(dòng)元素:float除了none以外的值猜嘱;
如float:left; 該元素屬性本身也產(chǎn)生了相應(yīng)的塊級格式化上下文衅枫。該元素產(chǎn)生的BFC與所在的根元素的BFC互不影響,此元素的作用域朗伶,則為該元素服務(wù)弦撩,與根元素產(chǎn)生一個(gè)隱形的邊界
(3)絕對定位元素:position
為absolute
或fixed
;
(4)display
為inline-block
(非塊盒的塊容器), flex
, 或inline-flex
论皆;
(5)overflow
除了visible
以外的值(hidden
益楼、auto
、scroll
)
3纯丸、應(yīng)用
這里的例子截取自該文章:
(1)功能1:
讓兩個(gè)相鄰的元素界限分明(同一個(gè) BFC 下外邊距會(huì)發(fā)生重疊或合并)
代碼如下:
<head>
div{
width: 100px;
height: 100px;
background: lightblue;
margin: 100px;
}
</head>
<div></div>
<div></div>
從效果上看偏形,因?yàn)閮蓚€(gè) div 元素都處于同一個(gè) BFC 容器下 (這里指 body 元素) 所以第一個(gè) div 的下邊距和第二個(gè) div 的上邊距發(fā)生了重疊,所以兩個(gè)盒子之間距離只有100px觉鼻,而不是 200px俊扭。
如圖:
首先這不是 CSS 的bug,我們可以理解為一種規(guī)范坠陈。如果想要避免外邊距的重疊萨惑,可以將其放在不同的 BFC 容器中。
<div class="container">
<p></p>
</div>
<div class="container">
<p></p>
</div>
<style>
.container {
overflow: hidden; ??
}
p {
width: 100px;
height: 100px;
background: lightblue;
margin: 100px;
}
</style>
這時(shí)候仇矾,兩個(gè)盒子邊距就變成了 200px 庸蔼,
如圖:
(2)功能2:
子元素被父元素包裹起來(BFC可以包含浮動(dòng)的元素)(可代替clearfix
來清除浮動(dòng))
-
display:flow-root;
讓當(dāng)前元素觸發(fā)BFC(正交,考慮瀏覽器兼容) -
overflow:hidden;
將溢出隱藏浮動(dòng)的元素會(huì)脫離普通文檔流贮匕,
來看下下面一個(gè)例子姐仅,代碼如下:
<style>
.father{
border: 1px solid #000;
}
.son{
width: 100px;
height: 100px;
background: #eee;
float: left;
}
</style>
<div class=father>
<div class=son></div>
</div>
由于父元素(father)內(nèi)子元素(son)進(jìn)行浮動(dòng),脫離了“父親”的文檔流刻盐,所以容器只剩下 2px 的邊距高度掏膏。此時(shí)可以觸發(fā)容器的 BFC,那么“father”就可以包裹住“son”出去的浮動(dòng)元素敦锌。
<style>
.father{
border: 1px solid #000;
overflow:hidden; ??
}
.son{
width: 100px;
height: 100px;
background: #eee;
float: left; ??
}
</style>
<div class=father>
<div class=son></div>
</div>
(3)功能3:
BFC 可以阻止元素被浮動(dòng)元素覆蓋
先來看一個(gè)文字環(huán)繞效果馒疹,代碼如下:
<style>
.box1{
height: 100px;
width: 100px;
float: left;
background: lightblue;
}
.box2{
width: 200px;
height: 200px;
background: #eee;
}
</style>
<div class=box1>我是一個(gè)左浮動(dòng)的元素</div>
<div class=box2>我是一個(gè)沒有設(shè)置浮動(dòng), 也沒有觸發(fā) BFC 元素, width: 200px; height:200px; background: #eee;</div>
此時(shí),浮動(dòng)元素浮在第二個(gè)元素上乙墙,第二個(gè)元素有部分區(qū)域被浮動(dòng)元素所覆蓋(但文本信息不會(huì)被浮動(dòng)元素所覆蓋) 颖变。如果想避免元素被覆蓋,可觸第二個(gè)元素的 BFC 特性听想,在第二個(gè)元素中加入overflow: hidden腥刹;
或者 display: flow-root;
<style>
.box1{
height: 100px;
width: 100px;
float: left; ??
background: lightblue;
}
.box2{
width: 200px;
height: 200px;
background: #eee;
overflow:hidden; ??
/*或 display: flow-root; */ ??
}
</style>
<div class=box1>
我是一個(gè)左浮動(dòng)的元素
</div>
<div class=box2>
我是一個(gè)沒有設(shè)置浮動(dòng), 也沒有觸發(fā) BFC 元素, width: 200px; height:200px; background: #eee;
</div>
就會(huì)變成:
BFC 浮動(dòng)處理
用來實(shí)現(xiàn)兩列自適應(yīng)布局:即左邊寬度固定,如果想右邊的內(nèi)容自適應(yīng)寬度汉买,可以去掉上面右邊內(nèi)容的寬度(如果右邊定寬肛走,窄頁面時(shí),則會(huì)自動(dòng)換到下一行排列)
二、邊距合并
1朽色、講例子
案例1:
當(dāng)實(shí)際中希望#header
和h1
之間產(chǎn)生一點(diǎn)縫隙(或間距)邻吞,即使將h1設(shè)置 margin:50px;
,作為塊級元素的h1
葫男,margin
左右生效抱冷,而上下則是#header+h1
整體向下移動(dòng)50px
這便是,外邊距合并
案例2:
看案例似乎是
<h1>
和<p>
標(biāo)簽所設(shè)置的外邊距各30px梢褐,兩者之間的間距理論來講應(yīng)該是60px旺遮,但事實(shí)上這是兩個(gè)相鄰元素的外邊距產(chǎn)生合并,下邊距<margiin-bottom>
和上邊距<margin-top>
合并之后取較大值盈咳,這里為30px這也是耿眉,外邊距合并
2、合并場景
(1)相鄰元素合并
同案例2
(2)父子合并
h1
和header
鱼响,或者再嵌套元素或者與其的祖先元素嵌套鸣剪,均能產(chǎn)生外邊距合并,這些都能稱之為“父子合并” ,如圖:
(3)自己合并
如圖丈积,塊級元素合并筐骇,無默認(rèn)樣式即靠在一起;含有p標(biāo)簽(含內(nèi)容)的塊級元素江滨,則有默認(rèn)上下margin
铛纬,所以detail
和footer
則會(huì)產(chǎn)生縫隙(或間距)
.footer
元素為空內(nèi)容,設(shè)置 margin:30px;
唬滑,即說明上邊距和下邊距合并后的外邊距總值是60px告唆,不過.footer
元素為空內(nèi)容,所以頁面效果仍然呈現(xiàn)30px晶密,說明css元素中外邊距合并的另一種情況:
自己和自己合并:如圖悔详,
三、取消合并(如何去解決外邊距合并惹挟?)
1、邊框缝驳、padding
存在于父子合并
為何#header
和h1
能夠產(chǎn)生合并连锯?即#header
沒有border和padding(即一個(gè)可與外界隔離的邊界線),導(dǎo)致h1
自帶的一個(gè)margin
用狱,沖出該邊界运怖,與#header
合并
嘗試在#header
里添加邊框(圖1)或者加padding
(內(nèi)邊距)(圖2),讓#header
和h1
的margin-top
夏伊,內(nèi)外分開摇展,即能做到不讓外邊距合并,如圖:
2溺忧、BFC
如何讓一個(gè)元素生成bfc咏连?bfc可認(rèn)為是擁有一片獨(dú)立的空間盯孙,和其他的空間(或其他的文檔流)區(qū)別開。注:添加bfc元素屬性祟滴,可以取消合并有可能產(chǎn)生副作用
(1)父子元素不產(chǎn)生合并
A振惰、添加:overflow:hidden;
B垄懂、添加 :float:left;
C骑晶、添加: display:inline-block;
D、添加: position:absolute;
(2)相鄰元素不產(chǎn)生合并
A草慧、添加:浮動(dòng)元素
B桶蛔、添加:overflow:hidden;
生成BFC漫谷,相當(dāng)于生成了一個(gè)邊界仔雷,即邊框作為一個(gè)邊界,有了邊界之后抖剿,#header+h1
父子元素便不能沖破該邊界朽寞,自然與#detail
元素的不產(chǎn)生合并.
【重點(diǎn)】:
而相鄰元素之間的margin
,可以認(rèn)為不是該父子元素邊界內(nèi)斩郎,同樣會(huì)產(chǎn)生合并脑融。
通常處理相鄰元素之間的間距合并問題(除浮動(dòng)外,浮動(dòng)時(shí)不會(huì)被合并)缩宜,即不考慮合并問題肘迎,直接設(shè)置為:margin-top:___px;