常规流之块级格式化上下文(Block Formatting Contexts)
在css2.1中,常規(guī)流包括塊框(block boxes)的塊格式化(block formatting),行內(nèi)框(inline boxes)的行內(nèi)格式化(inline formatting),塊級(jí)框(block-level-boxes)或行內(nèi)級(jí)框(inline-level-boxes)的相對(duì)定位。常規(guī)流中的框?qū)儆谝粋€(gè)格式化上下文,可能是塊或者是行內(nèi),但不能同時(shí)都是。塊級(jí)框參與塊級(jí)格式化上下文,行內(nèi)級(jí)框參與行內(nèi)級(jí)格式化上下文。今天我們先來說說塊級(jí)格式化上下文,也就是我們常說的BFC。
一.形成塊級(jí)格式化上下文
- 絕對(duì)定位元素(fixed其實(shí)是absolute的一個(gè)子集)
- display為inline-block,table-cell,table-caption,flex,inline-flex(這里有一點(diǎn)要注意的,display-table本身不會(huì)形成BFC,但是它會(huì)產(chǎn)生匿名框,其中包含的dispaly:table-cell元素會(huì)形成BFC)
- overflow不為visible
- 根元素
- float屬性不為none
這里要說明的是這些是形成塊格式化上下文,而不是說是參與塊級(jí)格式化上下文,這兩個(gè)概念很容易弄混,大家可以仔細(xì)體會(huì)下。塊格式化上下文是一個(gè)獨(dú)立的渲染區(qū)域,而且只會(huì)有塊級(jí)框(block-level box)來參與,它規(guī)定內(nèi)部的塊級(jí)框如何布局,與這個(gè)區(qū)域的外部毫不相干。
二.塊格式化上下文中的特性
? 在塊格式化上下文中,框會(huì)一個(gè)接一個(gè)的被垂直放置,他們的起點(diǎn)是一個(gè)包含塊的頂部。
兩個(gè)兄弟框之間的垂直距離取決于margin屬性。在BFC中相鄰的塊級(jí)元素的垂直邊距會(huì)折疊。
在BFC中,每一個(gè)元素的左外邊(left margin邊界)與包含塊的左邊相接觸(對(duì)于從右到左的格式化,右邊距接觸包含塊右邊)。即使存在浮動(dòng)也是如此(盡管一個(gè)元素的內(nèi)容區(qū)域會(huì)由于浮動(dòng)而壓縮),除非這個(gè)元素也形成了一個(gè)新的BFC。
計(jì)算BFC高度的時(shí)候,浮動(dòng)子元素也會(huì)參與計(jì)算。
BFC的區(qū)域不會(huì)與float box重疊。
三.塊級(jí)格式化上下文的作用
我們之所以要了解一些東西,無非是需要有現(xiàn)實(shí)的意義和作用,不然誰管它(笑)。
那么BFC有什么作用呢,那就得從BFC的特性說起了。下面,我們會(huì)根據(jù)一些具體的例子來一個(gè)個(gè)說明。
1.清除浮動(dòng)
我們上面說了,計(jì)算BFC高度的時(shí)候,浮動(dòng)子元素也會(huì)參與計(jì)算,而浮動(dòng)子元素造成的塌陷想必大家也都非常了解,那么如果父元素形成了BFC,是不是就可以包含浮動(dòng)子元素了呢?直接看例子(為了直觀我就不貼可運(yùn)行代碼了):
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>BFC清除浮動(dòng)</title><style>*{margin:0; padding: 0;}.wrap-wrap{ height: 150px;}.wrap{ width: 300px; background-color :#fcc; color: #fff;}.son1,.son2{ float: left; width: 100px; height: 100px; background-color:red;}.son2{ background-color:blue; }.wrap-bfc{ overflow: hidden;}</style> </head> <body> <div class="wrap-wrap"><div class="wrap">wrap<div class="son1">son1</div><div class="son2">son2</div></div> </div> <div class="wrap wrap-bfc">wrap<div class="son1">son1</div><div class="son2">son2</div> </div> </body> </html>運(yùn)行結(jié)果如下:
我們通過一個(gè)overflow:hidden使下面的wrap形成了BFC,它高度的計(jì)算中浮動(dòng)子元素也會(huì)參與,自然就包含了浮動(dòng)元素,從而達(dá)到了清除浮動(dòng)的目的。當(dāng)然,不止overflow:hidden可以清除浮動(dòng),各位可以自行試試其他屬性。
2.防止垂直margin重疊
在同一BFC中相鄰的塊級(jí)元素的垂直邊距會(huì)折疊。那么如果這兩個(gè)元素不在一個(gè)BFC中了會(huì)發(fā)生什么呢,繼續(xù)看例子:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>防止邊距折疊</title><style>*{margin:0; padding: 0;}.wrap,.wrap1,.wrap2{ width: 200px; height: 100px; background-color :#fcc; color: #fff;}.son1,.son2{ width: 50px; height: 20px; margin: 10px; background-color:red;}.son2{ background-color:blue; }.wrap1{ overflow: hidden; background-color:lime; }.wrap2{ overflow: hidden; background-color:lime; }.new-wrap{ overflow: hidden;}</style></head> <body><div class="wrap"><div class="son1">son1</div><div class="son2">son2</div>wrap</div><p>——————分割符————</p><div class="wrap1"><div class="son1">son1</div><div class="son2">son2</div>wrap1</div><p>——————分割符————</p><div class="wrap2"><div class="son1">son1</div><div class="new-wrap"><div class="son2">son2</div></div>wrap2</div> </body> </html>
?
運(yùn)行結(jié)果如下:
這里有兩點(diǎn)要說。
1).wrap1與son1的margin折疊
我們先看wrap,son1是有個(gè)margin-top,但是圖中給我們的感覺是沒有,反而是它的父元素wrap有一個(gè)margin-top。為什么呢,這個(gè)就要看magrin折疊的說明了,這個(gè)也是標(biāo)準(zhǔn)中的內(nèi)容:
In this specification, the expression?collapsing margins?means that adjoining margins (no non-empty content, padding or border areas or clearance separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin.?所有毗鄰的兩個(gè)或更多盒元素的margin將會(huì)合并為一個(gè)margin共享之。毗鄰的定義為:同級(jí)或者嵌套的盒元素,并且它們之間沒有非空內(nèi)容、Padding或Border分隔。
可知嵌套的盒元素也會(huì)Collapsing Margins,就不難知道為什么會(huì)這樣了。而在wrap1中,同樣的結(jié)構(gòu),也沒有非空內(nèi)容、Padding或Border分隔,為什么又不折疊了呢?這里就要知道什么叫毗鄰了:
Two margins are adjoining if and only if:
- both belong to in-flow block-level boxes that participate in the same block formatting context
- no line boxes, no clearance, no padding and no border separate them (Note that certain zero-height line boxes (see 9.4.2) are ignored for this purpose.)
- both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
- top margin of a box and top margin of its first in-flow child
- bottom margin of box and top margin of its next in-flow following sibling
- bottom margin of a last in-flow child and bottom margin of its parent if the parent has 'auto' computed height
- top and bottom margins of a box that does not establish a new block formatting context and that has zero computed 'min-height', zero or 'auto' computed 'height', and no in-flow children
我就不一個(gè)個(gè)翻譯了,就看第一條,這些margin都處于普通流中,并在同一個(gè)BFC中。我自己的理解是下面這樣的,不一定正確,如果知道的同學(xué)還請(qǐng)指正:
wrap1的overflow:hidden屬性形成了一個(gè)新的BFC,son1就參與了這個(gè)新的BFC。而wrap1本身是在根元素形成的BFC種,由此兩個(gè)就不在同一個(gè)BFC中了,也就不是毗鄰的了,自然margin不會(huì)折疊。
2).son1與son2的邊距折疊。
根據(jù)上面一點(diǎn)說的,son1和son2是滿足margin折疊的條件的,那么如果我們給son2包裹個(gè)new-wrap,并讓它形成BFC,自然就沒有邊距折疊了。
?
3.自適應(yīng)兩欄布局。
這個(gè)直接上代碼吧,根據(jù)例子來說,比較直觀
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>自適應(yīng)布局</title><style>*{margin:0; padding: 0;}body {position: relative;color: #fff;}.aside {width: 100px;height: 150px;float: left;background: #f66;}.main {height: 200px;background: #fcc;}</style> </head> <body><div class="aside">float aside</div><div class="main">main</div> </body> </html>運(yùn)行結(jié)果:
這里首先要說的是main的位置問題。在BFC中,每一個(gè)元素的左外邊(left margin邊界)與包含塊的左邊相接觸(對(duì)于從右到左的格式化,右邊距接觸包含塊右邊),這里雖然有float的aside,但是main的左邊依然與包含塊的左邊接觸。
而如果我們對(duì)main設(shè)置這樣的樣式:main:overflow:hidden,結(jié)果如下:
當(dāng)觸發(fā)main生成BFC后,這個(gè)新的BFC不會(huì)與浮動(dòng)的aside重疊。因此會(huì)根據(jù)包含塊的寬度,和aside的寬度,自動(dòng)變窄。為什么呢:
BFC的區(qū)域不會(huì)與float box重疊。
四.總結(jié)
今天我們主要分析了什么是BFC、怎么形成BFC以及BFC的作用。其中有一些我總結(jié)個(gè)人的理解,希望對(duì)大家有幫助。另外,在css3的草案中,對(duì)這個(gè)概念做了改動(dòng),將Block?formatting?context?叫做?flow?root,觸發(fā)方式也發(fā)生了變化:The value of 'position' is neither "static" nor "relative".fixed作為absolute的一個(gè)子類也會(huì)形成flow root,有興趣的同學(xué)可以自己去了解下。好了,就這么多了,我寫東西都是準(zhǔn)備好了然后一口氣,后面再一點(diǎn)點(diǎn)修改,初成文難免會(huì)有錯(cuò)漏,還請(qǐng)大家多多指正。下一章會(huì)分析下行內(nèi)級(jí)格式化上下文的相關(guān)。
?
?
參考:
1.KB010: 常規(guī)流( Normal flow )
2.w3c盒模型
3.w3c常規(guī)流
4.前端精選文摘:BFC 神奇背后的原理
轉(zhuǎn)載于:https://www.cnblogs.com/rexD/p/4597380.html
總結(jié)
以上是生活随笔為你收集整理的常规流之块级格式化上下文(Block Formatting Contexts)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CString与std::string
- 下一篇: deLPHI书籍名称