BFC是Block Formatting Context的缩写,全称为块级格式化上下文。BFC也是一个盒子(只不过看不见)
一、如何形成BFC
满足以下条件之一,便可形成BFC:
- float属性不为
none
- postion属性不为
static
和relative
(即为absolute
和fixed
) - display为
table-cell
、table-caption
、inline-block
、flex
、inline-flex
之一 - overflow的属性不为
visible
虽然有如此多的条件可以形成BFC,但是不少条件会有些多多少少的副作用
(属性设置带来的表现),如:
- overflow: scroll 会有滚动条
- float: left 使元素浮动
所以,其实建立BFC最好的方式,便可以是overflow: hidden
二、BFC布局
根据W3C规范:
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)
翻译过来则是:
在块级格式化上下文(BFC)中,每个盒子的左边界,都向着容纳块(Containing block)的左边靠齐(对于右到左格式,则是向右靠齐)。对于float的情况下,也是如此(尽管一个盒子的线框可能会因为浮动而缩小),除非盒子建立了一个新的BFC(某些情况下盒子本身会因为浮动而变得狭小)
所以,BFC有什么用呢?
三、BFC应用
1、利用BFC消除Margin Collapse
正常的情况下,一个容器内的所有盒子都会由上而下垂直排列(一个块级元素占一行)。而且,我们会发现,如果相邻的两个盒子都设置了margin属性,则margin属性并不会叠加(取垂直方向上叠加的两个margin分量的最大值),如:
<style type="text/css">
.box { }
.box .s1 { height: 20px; background: #CCC; margin-bottom: 10px; }
.box .s2 { height: 20px; background: #CCC; margin-top: 10px; }
</style>
<div class="box">
<div class="s1"></div>
<div class="s2"></div>
</div>
那么,这种情况下,s1和s2两个DIV的间距并不会是我们期望的20px
,而是只有10px
对于处在同一个BFC的元素来说,便会发生Margin Collapse现象,而处于不同的BFC的元素,就不会发生,所以,为了解决这个问题,我们需要的就是新建一个BFC,如:
<style type="text/css">
.box { }
.box .s1 { height: 20px; background: #CCC; margin-bottom: 10px; }
.box .s2 { height: 20px; background: #CCC; margin-top: 10px; }
</style>
<div class="box">
<div class="s1"></div>
<div style="overflow:hidden">
<div class="s2"></div>
</div>
</div>
现在,s1和s2的间距是20px了
2、利用BFC容纳浮动元素
如果一个容器里包含有浮动元素,就有可能遭遇到容器高度为0的情况。如:
<style type="text/css">
.box { background: #000 }
.box .s1 { height: 20px; width: 100px; background: #CCC; float: left; }
.box .s2 { height: 20px; width: 100px; background: #CCC; float: left; }
</style>
<div class="box">
<div class="s1">1</div>
<div class="s2">2</div>
</div>
这种情况下,box的高度会是0。所以,为了解决这个问题,我们除了可以使用::after
来添加clear:both
外,还可以建立一个BFC,让它容纳浮动元素,如:.box { background: #000; overflow: hidden }
3、利用BFC阻止文本换行
在一般情况下,文本会围绕浮动元素。而有时候,我们不希望它围绕浮动元素,这种情况下,仍然可以利用BFC
因为浮动元素的移动,导致文本不得不移动来腾出位置。但是随着文本的增多,文本高度超过浮动元素的部分就不会在水平方向上挪出位置,所以便会导致看起来像是环绕。所以,这种情况下,我们为了实现figure2的效果,就可以用一个BFC包围文本,使得有一个统一的左边界,这样子的情况下,就不会再环绕浮动元素了,如:
<style type="text/css">
.box { width: 300px; }
.box img { width: 100px; float: left; }
.box p { overflow: hidden; }
</style>
<div class="box">
<img src="pic.jpg" />
<p>一大段文字,一大段文字,一大段文字,一大段文字,一大段文字,一大段文字,一大段文字,一大段文字,一大段文字,一大段文字,一大段文字,一大段文字,一大段文字,一大段文字</p>
</div>