BFC是什么?
BFC(block formatting context)块级格式化上下文,之前经常听说BFC,也一直一知半解,觉得其很是神秘。最近找工作,于是认真学习了一下,发现其实并没有想象那么难以理解。简而言之,BFC是页面上隔离的一个独立容器,它不会与容器外的其他元素互相影响。举个例子,你可以理解页面的根元素<html>就是一个BFC,它里面的子元素的定位等只与<html>这个根元素有关,而与其他的页面无关。当元素是一个BFC时,它会有自己的一套页面渲染或者计算规则。
BFC的创建条件
首先,我们来学习一下什么情况下会创建一个BFC。
- 根元素
- 元素浮动
- 元素position为absolute,fixed
- 元素overflow值不为visible
- 元素display的值为inline-block,table-cell,table-caption
- 等等...(详细可以参见块格式化上下文)
BFC的渲染规则口诀
当一个元素形成一个BFC时,它可以帮助我们解决很多样式问题。在介绍BFC大法之前,你需要记住以下口诀:
- 当一个元素满足了xxx条件,该元素就成为一个BFC
- 当一个元素是一个BFC,则会满足一些渲染规则
BFC渲染规则
在背熟以上口诀后,我们就来造轮子举例,细细说一说BFC的渲染规则,下面请看重点
1. BFC在计算自身高度时会包含内部的浮动元素
在使用浮动样式时,常常会造成父级容器的高度塌陷,例如:
<style>
.parent {
border: 1px solid green;
width: 600px;
}
.child {
height: 100px;
width: 400px;
background: yellow;
}
.float {
float: left;
height: 100px;
width: 400px;
background: orange;
}
</style>
<div class="parent">
<div class="child"></div>
<div class="float"></div>
</div>
当我们给.parent元素加上
overflow:auto时,满足上面条件4,因此parent元素会形成一个BFC,在计算自身高度时会包含内部的浮动元素
.parent{
border: 1px solid green;
width: 600px;
overflow:auto;
}
2. BFC不会与其他的兄弟元素发生关系,因此可以防止元素间的margin重叠
我们知道,内容在垂直方向上两个相邻div的margin会发生重叠,会以两个元素margin中最大的那个作为两个元素间的实际margin,这个时候就造成了margin垂直方向上的重叠。举例如下:
<style>
.child1{
height: 100px;
width: 300px;
background: yellow;
margin: 20px;
}
.child2{
height: 100px;
width: 300px;
background: orange;
margin: 20px;
}
</style>
<div>
<div class="child1"></div>
<div class="child2"></div>
</div>
结果出来的布局效果却是
margin:20px,由于相邻元素的margin垂直方向上会重叠,因此两个元素只有20px的margin。
为了防止margin的重叠,我们可以在child2元素外面包裹一层div,设置其overflow:auto,使之成为一个BFC,这样BFC便不会与外界相邻元素发生关系,有效解决了该问题。
<style>
.child1{
height: 100px;
width: 300px;
background: yellow;
margin: 20px;
}
.child2{
height: 100px;
width: 300px;
background: orange;
margin: 20px;
}
.bfc{
overflow: auto;
}
</style>
<div>
<div class="child1"></div>
<div class="bfc">
<div class="child2"></div>
</div>
</div>
设置以上样式之后,.bfc形成了一个BFC,不会与外界相邻元素发生关系。
3. BFC不会与浮动元素重叠,因此可以简单的实现双栏布局
在页面布局中,我们常常会用到左侧菜单栏,右侧主体内容的双栏布局。在实践中,我们常采用以下的方式实现。即左侧浮动,右侧margin-left:左侧浮动的宽度。
用以上样式便可以轻松实现两栏布局,就像这样,左边侧边栏,右侧主体内容。
overflow:auto,使其成为一个BFC,这样它自己占有的区域不会和浮动元素发生重叠,就可以通过BFC的渲染规则轻松的实现两栏布局了。
<style>
.body-wrap{
height: 100px;
}
.left{
float:left;
width: 200px;
height: 100%;
background: blue;
opacity: 0.5;
}
.right{
height: 100%;
overflow:auto;
background: yellow;
}
</style>
<div class="body-wrap">
<div class="left"></div>
<div class="right"></div>
</div>
效果如下:
4. BFC内的浮动不会影响到BFC外部的元素,实际应用为清除浮动
<style>
.parent{
overflow:auto;
width: 600px;
}
.float{
float:left;
height:100px;
width: 100%;
}
.child1{
background: orange;
}
.child2{
background: yellow;
}
</style>
<div class="parent">
<div class="child1 float"></div>
<div class="child2 float"></div>
</div>
可以设置.parent元素为overflow:auto,为一个BFC,采用这种方式可以清除浮动。但是对于清除浮动方法来说,这种方式在对于一些应用性样式上存在一定局限性,所以用得较少。
看了上面四个例子,是不是觉得BFC好像也没有那么难以理解了呢,大家主要记住一句话,当一个元素拥有某些样式设置时如overflow:auto等会使该元素成为一个BFC,当一个元素形成BFC时,会有自己的一套渲染规则,我们可以使用这些规则解决样式应用中的一些实际问题。
参考
以上,有写的不对的地方请大家指正、探讨。