CSS系列-BFC
什么是BFC
- BFC全称是Block Formatting Context,即块格式化上下文。
- 它是CSS2.1规范定义的,关于CSS渲染定位的一个概念。
形成BFC的条件
- 浮动元素, float 不是 none;
- 定位元素,postiton 值为 fixed、absolute;
- overflow 是除了 visible 的值,(auto, scroll, hidden);
- display 是下面的值 inline-block、table、table-cell、table-caption;
- 弹性盒子 display 是flex、inline-flex,以及它的子元素
BFC的特性
- 内部的盒会在垂直方向一个接一个排列(这条特性不必纠结,即便不在BFC里块级盒子也会垂直排列)
- 处于同一个BFC中的元素相互影响,可能会发生margin 重叠(两个兄弟盒子之间的垂直距离不是他们的两个外边距之和,而是以较大的为准)
- 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此;
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素(解决margin重叠)
- 计算BFC的高度时,浮动元素也参与计算 (解决高度塌陷);
- BFC区域不会与float重叠(意思是说,2个盒子,div1和div2,div2紧跟着div1下面,如果div1是左浮动, 那么div2会和div1重叠, 解决这个问题就是让div2产生BFC);
BFC的范围
一个BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。这段看上去有点奇怪,
我是这么理解的,加入有下面代码,class名为.BFC
代表创建了新的块格式化:
<div id='div_1' class='BFC'>
<div id='div_2'>
<div id='div_3'></div>
<div id='div_4'></div>
</div>
<div id='div_5' class='BFC'>
<div id='div_6'></div>
<div id='div_7'></div>
</div>
</div>
#div_1
创建了一个块格式上下文,这个上下文包括了#div_2
、#div_3
、#div_4
、#div_5
。即#div_2
中的子元素也属于#div_1
所创建的BFC。- 但由于
#div_5
创建了新的BFC,所以#div_6
和#div_7
就被排除在外层的BFC之外。 - 我认为,这从另一方角度说明,一个元素不能同时存在于两个BFC中。
例子:
1. 浮动的盒子会遮盖下面的盒子,但是下面盒子里的文字是不会被遮盖的,文字反而还会环绕浮动的盒子。这也是一个比较有趣的特性。下面黄色区域添加做浮动;
可以在绿色区域产生BFC解决这个问题:
2. 两栏布局:
效果:左边固定宽度,右边的宽度自适应,随浏览器窗口大小的变化而变化。
实现:左边固定宽度,设置浮动; 右边不设宽,使其产生BFC
实例一
<style>
* {
margin: 0;
padding: 0;
}
.left{
background: #73DE80; /* 绿色 */
opacity: 0.5;
border: 3px solid #F31264;
width: 200px;
height: 200px;
float: left;
}
.right{
background: #EF5BE2;/* 粉色 */
opacity: 0.5;
border: 3px solid #F31264;
width:400px;
min-height: 100px;
}
.box{
background:#888;
height: 100%;
margin-left: 50px;
}
</style>
<div class='box'>
<div class='left'> </div>
<div class='right'> </div>
</div>
显示效果:( 绿色与粉色重叠,父盒子没有计算绿色的高度 )
绿色框(’#left’)向左浮动,它创建了一个新BFC,由于绿色框浮动了,脱离了原本normal flow的位置,因此粉色框(’#right’)就被定位到灰色父元素的左上角(特性:元素左边与容器左边相接触),与浮动绿色框发生了重叠。
由于灰色框(’#box’)并没有创建BFC,因此在计算高度的时候,并没有考虑绿色框的区域,发生了高度坍塌,这也是常见问题之一。
实例二
现在通过设置overflow:hidden
来创建BFC,再看看效果如何。
.BFC{
overflow: hidden;
}
<div class='box BFC'>
<div class='left'> </div>
<div class='right'> </div>
</div>
显示效果:(特性:计算BFC的高度时,浮动元素也参与计算)
灰色框创建了一个新的BFC后,高度发生了变化,计算高度时它将绿色框区域也考虑进去了;
实例三
现在,现将一些小块添加到粉色框中,看看效果:
<style>
.little{
background: #fff;
width: 50px;
height: 50px;
margin: 10px;
float: left;
}
</style>
<div class='box BFC'>
<div class='left'> </div>
<div class='right'>
<div class='little'></div>
<div class='little'></div>
<div class='little'></div>
</div>
</div>
显示效果:由于粉色框没有创建新的BFC,因此粉色框中白色块受到了绿色框的影响,被挤到了右边去了。
实例四
利用同实例二中一样的方法,为粉色框创建BFC:
<div class='box BFC'>
<div class='left'> </div>
<div class='right BFC'>
<div class='little'></div>
<div class='little'></div>
<div class='little'></div>
</div>
</div>
显示效果:
一旦粉色框创建了新的BFC以后,粉色框就不与绿色浮动框发生重叠了,同时内部的白色块处于隔离的空间(特性:BFC就是页面上的一个隔离的独立容器),白色块也不会受到绿色浮动框的挤压。