初學CSS時,我們學到很多有意思的CSS規則,比如外邊距塌陷,還有浮動元素的一些特性等,其實這些規則背后都是BFC這個東西在控制,下面我們來看下BFC到底是什么。
什么是BFC
BFC(Block formatting contexts),翻譯過來就是塊級格式化上下文,指的是一種上下文環境,我們暫且不管它為什么叫這么晦澀冗長的名字,先看看哪些情況能形成BFC,然后看看它有哪些特性,這樣我們也就知道它是什么了。就像我們學習js的對象一樣,了解一個對象的原型,以及它的屬性方法,我們也就知道它是什么了。
如何形成BFC
根據W3C的定義:浮動元素,絕對定位元素,非塊級盒子的塊級容器(例如inline-blocks,table-cells,and table-captions),以及overflow屬性值不是“ visible”(visible是overflow的默認值)的塊級盒子(視口除外),這些元素就會為他們的內容創建一個BFC。
BFC的特點
在一個BFC中,垂直方向上,盒子是從包含塊頂部開始一個挨著一個布局的,兩個相鄰的盒子的垂直距離是由margin屬性決定的,在一個BFC中的兩個相鄰的塊級盒子的垂直外邊距會產生塌陷。
在一個BFC中,水平方向上,每個盒子的左邊緣都會接觸包含塊的左邊緣(從右向左的格式則相反)。除非出現浮動元素和其他元素相互作用的情況(當有浮動元素時,行盒可能因浮動元素而收縮,如果有盒子形成了新的BFC,那這個盒子也可能因浮動元素而變窄)。
這樣我們終于知道為什么《精通CSS》里提到外邊距塌陷時,為什么設置這么多的條件了:
- 處于文檔流中的塊級元素
- 垂直外邊距直接相遇
其中第一個條件就是為了防止形成BFC,我們要注意的是BFC內部的子元素之間可以形成外邊距塌陷,但BFC元素和其他塊級元素是不能形成外邊距塌陷的。
BFC的應用
BFC的應用場景比較多,在這里列一些我臨時想到的
-
清除元素之間的影響
如果想讓一個元素不受另一個元素的影響,可以把其中一個元素放到BFC環境中。
eg:我們都知道文本會圍繞著浮動元素布局,如下圖所示
<style type="text/css">
.out{
width: 200px;
height: 200px;
border: 1px solid blue;
}
.f{
width: 50px;
height: 50px;
background: red;
float: left;
}
</style>
<div class="out">
<div class="f"></div>我是文本我是文本我是文本我是文本我是文本我是文本我是文本
我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本</div>
如果我們不想讓文本環繞,只想讓文本位于右側,怎么處理呢?
只需要在文本外套一層元素,并且把這個元素變成BFC,這樣文本就不會受到浮動元素的影響了。我這里通過修改overflow屬性使文本所在元素形成一個BFC。
<style type="text/css">
.out{
width: 200px;
height: 200px;
border: 1px solid blue;
}
.f{
width: 50px;
height: 50px;
background: red;
float: left;
}
.inner{
overflow: auto;
}
</style>
<div class="out">
<div class="f"></div><div class="inner">我是文本我是文本我是文本我是文本我是文本我是文本我是文本
我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本</div></div>
防止塊級元素之間外邊距塌陷的方法之一就是利用剛才說的第一個條件,也是同樣的原理,形成一個BFC,在這里就不再說了。
-
清除內部浮動元素對父級元素的影響
eg:
<style type="text/css">
.out{
border: 1px solid blue;
}
.f{
width: 50px;
height: 50px;
background: red;
float: left;
}
</style>
<div class="out">
<div class="f"></div>
</div>
效果圖:
如果想讓外部元素包含浮動元素,只需將外部元素設置為BFC
<style type="text/css">
.out{
overflow: auto;
border: 1px solid blue;
}
.f{
width: 50px;
height: 50px;
background: red;
float: left;
}
</style>
效果圖:
-
創建自適應布局
如果我們想創建一個兩列布局,其中左側寬度不定,右側寬度自適應占用剩下的空間,有一種方法就是利用浮動元素和BFC元素的相互作用實現的。
<style type="text/css">
html,body{
width: 100%;
height: 100%;
}
.out{
background: blue;
width: 100%;
height: 100%;
}
.f{
float: left;
margin-right: 20px;
height: 100%;
background: red;
}
.r{
overflow: auto;
height: 100%;
background: yellow;
}
</style>
<div class="out">
<div class="f">浮動元素</div>
<div class="r"></div>
</div>
效果圖:
總結
BFC是很多CSS規范背后的原理,所以有必要搞清楚BFC。
參考資料:
https://www.w3.org/TR/CSS2/visuren.html#block-formatting
http://www.w3cplus.com/css/understanding-bfc-and-margin-collapse.html