一、BFC是什么鬼?
相信做前端开发的人应该都听过BFC这个名词,起初,我也是在网上搜索资料时,看见过它,才去了解它,网上也有很多关于它的资料。
那么到底什么是BFC呢?
BFC(block formatting context)直译为“块格式化上下文”,是页面 CSS 视觉渲染这个过程中的一个概念。它是决定块盒子的布局及浮动元素相互影响的一个因素。
BFC是 W3C CSS 2.1 规范中的一个概念,它是一个独立的渲染区域,只有块级盒(block-level box)参与,它规定了内部的块级盒如何布局,并且与这个区域外部毫不相干。就个人简单理解来说就是,BFC这家伙可以将其下的盒子与外界隔离起来的,让它的子元素在里面玩耍,不会影响到外面的元素。更多具体的内容,大家可以网上自查资料。
二、触发BFC的情况,常见如下:
1、根元素或其它包含它的元素。
2、浮动元素(元素的 float 不为 none)
3、绝对定位元素 (元素的 position 为 absolute 或 fixed)
4、display的值为table-cell, table-caption, inline-block、display: flex 或 inline-flex的元素。
5、overflow的值为auto,scroll或hidden的元素
三、BFC的布局规则
1、在BFC中,其内部子元素从包含块顶部开始,按文档流垂直地一个接一个地排列。
2、相邻的两个元素之间的垂直距离由margin决定,属于同一个BFC的两个相邻块级盒的垂直margin会发生重叠。
3、在BFC中,每一个内部元素都会从包含块的左边界开始(对于从右向左的排版,则相反), 即使在有浮动元素参与的情况下也是如此(尽管一个元素的内容区域会由于浮动而压缩),除非这个元素也创建了一个新的BFC(在某些情况下这个元素自身会因为floats而变窄)。
4、BFC的区域不会与float块级盒重叠。
5、BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
6、在计算生成了BFC的元素的高度时,其浮动元素也参与计算。
也就是,当一个HTML元素满足上面条件的任何一条,都可以产生BFC。
四、关于BFC布局规则的原理说明和作用
下面通过简单的例子说明一下关于上面6条BFC布局的规则和作用。
1、在BFC中,其内部子元素从包含块顶部开始,按文档流垂直地一个接一个地排列。
关于这一条大家应该很好理解,下面先看代码例子:(例子中部分css直接写在style,代码不做优化)
<style type="text/css"> .box{width: 100px; height: 50px; line-height:50px; text-align: center; color: #fff;} .div0{background: #3ABF9A;} .div1{background: #3E3434;} .div2{background: #00BCD4;} </style> <div class="box div0">50px</div> <div class="box div1">50px</div> <div class="box div2">50px</div>
从上图中可知,这个三个div是从包含块顶部开始,在垂直方向上,从上到下,一个接一个的排列的。而这里的包含块元素是body。根据第三条,每一个内部元素都会从包含块的左边界开始。
2、两个相邻的元素之间的垂直距离由margin决定,属于同一个BFC的两个相邻Box的margin会发生重叠。
在上面的例子中,我们给三个div加边距看看。如下代码:
<div class="box div0" style="margin-bottom: 50px;">50px</div> <div class="box div1" style="margin: 50px 0 50px 0;">50px</div> <div class="box div2" style="margin-top: 50px;">50px</div>
从图中可知,他们的边距发生的了重叠,第一个margin-bottom:50px和第二个margin-top:50px发生重叠了变为50px了,第三个和第二个也是如此。
当我们在第二个div外面包一个div时,使其触发BFC,那么它里面的div和外面的2个div便不属于同一个BFC,就不会发生重叠了。如下所示:
<div class="box div0" style=" margin-bottom: 50px;">50px</div> <div style="overflow: hidden;"> <div class="box div1" style="margin: 50px 0 50px 0;">50px</div> </div> <div class="box div2" style="margin-top: 50px;">50px</div>
从图中可知,他们的边距不重叠了,垂直方向的间距变为100px了。如我们上面说的“BFC容器里面的子元素不会影响到外面的元素”。它的作用就是可以解决我们平时所说的垂直边距重叠的问题了。
4、在BFC中,每一个内部元素都会从包含块的左边界开始(对于从右向左的排版,则相反), 即使在有浮动元素参与的情况下也是如此(尽管一个元素的内容区域会由于浮动而压缩),除非这个元素也创建了一个新的BFC(在某些情况下这个元素自身会因为floats而变窄)。看如下代码:
<style type="text/css"> .div0{width:400px; height: 200px;} .div1{width: 100px; height: 50px; background: #3ABF9A; float: left;} .div2{width: 300px; height: 200px; background: #3E3434;} </style> <div class="div0"> <div class="div1"></div> <div class="div2"></div> </div>
从图中可知,div1元素虽然设置了浮动,但div2的左边依然是从包含块的左边界开始,div1和div2发生了重叠。符合我们上面所说的(即使在有浮动元素参与的情况下也是如此)。
5、BFC的区域不会与float块级盒重叠
有时候一个浮动元素后面跟着一个非浮动的元素,就会产生一个覆盖的现象,这时候非浮动的元素触发BFC就可以解决这个覆盖的现象了。
我们把上面的例子改改一下,使div2也触发BFC,div2会根据包含块的宽度,和div1的宽度,自动变窄了,自适应宽度,这时div1和div2就不重叠了,也就是说BFC的区域不会与float块级盒重叠了。如下所示:
<style type="text/css"> .div0{width:400px; height: 200px;} .div1{width: 100px; height: 50px; background: #3ABF9A; float: left;} .div2{width: 300px; height: 200px; background: #3E3434; overflow: hidden} </style> <div class="div0"> <div class="div1"></div> <div class="div2"></div> </div>
这也是我们平时常用来做两列自适应布局的方法(左边元素浮动,右边元素overflow: hidden触发BFC)。更多内容可以查看:
6、在计算生成了BFC的元素的高度时,其浮动元素也参与计算。
<style type="text/css"> .div0{width:400px; border:5px solid #ccc} .div1{width: 100px; height: 200px; background: #3ABF9A; float: left;} .div2{width: 200px; height: 100px; background: #3E3434; float: left;} </style> <div class="div0"> <div class="div1"></div> <div class="div2"></div> </div>
如上面代码所示,外部div0元素没有设置高度,其子元素使用浮动的时候,可以才看出两个div已经脱离了父元素的包含块,外围div0并没有自适应撑开高度(灰色部分)。
这时,我们可以闭合浮动,触发父元素的BFC,让父元素包含两个子元素,其实,当我们给div0加overflow: hidden触发BFC时,在计算高度时,两个浮动子元素就会参与。如下所示:
<style type="text/css"> .div0{width:400px; background: #ddd; overflow: hidden} .div1{width: 100px; height: 200px; background: #3ABF9A; float: left;} .div2{width: 200px; height: 100px; background: #3E3434; float: left;} </style> <div class="div0"> <div class="div1"></div> <div class="div2"></div> </div>
五、小结:
关于BFC,简单来说,BFC其实就是一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,既然这样,那么那些场景常用到BFC,常用有三个如下:
1、解决垂直边距重叠的问题
2、布局,比如两列自适应布局
3、可以用于清除浮动,计算BFC高度
以上是个人整理的关于理解BFC特性原理的一些简单笔记,如有错误,欢迎指正!
参考:
BFC 神奇背后的原理