想要了解BFC的规则,前提必须是熟悉前端网页的多种布局手段,例如盒的显示模式display,三种布局手段标准流(normal)、浮动流(float)、定位流(position)等。你只有熟练掌握了这些布局手段之后,才能很好的理解BFC。
BFC定义
BFC - Block Formatting Context 块级格式化上下文
官方解释:A block formatting context contains everything inside of the element creating it that is not also inside a descendant element that creates a new block formatting context.
解释:
一个BFC区域包含创建该上下文元素的所有子元素,但是不包括创建了新的BFC的子元素的内部元素
eg:
<div class="box1" id="bfc1">
<div class="box2"></div>
<div class="box3"></div>
<div class="box4" id="bfc2">
<div class="box5"></div>
<div class="box6"></div>
</div>
</div>
解释:
假定bfc1是一块BFC区域:
这块区域包含的box2、box3、box4都是bfc1的子元素
bfc4也创造了一块BFC区域:
包含box5、box6。
按官方文档的意思就是:
box1的BFC只包含box2、box3、box4
而不包含box5、box6
box4的BFC区域只包含box5、box6
- 每一个BFC区域只包括其子元素,不包括其子元素的子元素。
- 每一个BFC区域都是独立隔绝的,互不影响!
触发BFC
触发BFC的条件:
body根元素
设置浮动,不包括none
设置定位,absolute或者fixed
行内块显示模式,inline-block
设置overflow,即hidden,auto,scroll
表格单元格,table-cell
弹性布局,flex
并不是所有的元素都是BFC, 只有满足了上面的任意1个条件之后,这个元素才成为1个BFC。
一个BFC区域,只包含其所有子元素,不包含子元素的子元素。
BFC的特性
-
属于同一个BFC的两个相邻容器的上下margin会重叠
可用BFC解决margin重叠问题。 -
计算BFC高度时浮动元素也参于计算
解释为何BFC特性能解决父元素高度塌陷(BFC特性的浮动元素的高度也计算在父元素之内) -
BFC的区域不会与浮动容器发生重叠
-
BFC内的容器在垂直方向依次排列
(类似正常情况下块元素在垂直方向上依次排列) -
元素的margin-left与其包含块的border-left相接触
-
BFC是独立容器,容器内部元素不会影响容器外部元素
利用BFC解决问题
解决外边距的合并问题(垂直塌陷)
外边距合并: 指的是,当两个垂直外边距相遇时,它们将形成一个外边距。 合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。
造成外边距合并的三个原因:
-
发生在同一层相邻元素之间
解决: 将这两个盒子,放到两个BFC区域中
-
没有内容将父元素和后代元素分开
解决:就可以触发BFC,将父盒子变成一个独立的区域,这样在BFC区域内部的任何操作,都不会影响到外部。
目的:子元素距离父元素的顶部100px
结果:父级会和子级移动,距离顶部100px。
<div>
<p></p>
</div>
<style>
#box1{
width: 200px;
height:200px;
background:lightseagreen;
}
#box2{
width: 100px;
height:100px;
background:darkgoldenrod;
margin-top:50px ;
}
</style>
- 空的块级元素
只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并。
解决高度塌陷问题
阻止标准流元素被浮动元素覆盖
<style>
.box1 {
width: 120px;
height: 200px;
background-color: red;
float: left;
}
.box2 {
height: 300px;
background-color: skyblue;
}
</style>
<body>
<div class="box1"></div>
<div class="box2"></div>
</body>
红色盒子浮动,蓝色盒子时标准流
默认情况下,浮动元素覆盖了标准流元素
但是,如果将蓝色盒子的BFC触发,那么情况将有所变化。
当蓝色盒子触发了BFC之后,浮动元素再也不能覆盖它了,而且还能利用这个特性,来实现蓝色盒子宽度根据红色盒子的宽度来做自动适应。