BFC指的是块级格式化上下文,简单的来说,BFC就是创建一个盒子,盒子内部的元素布局不影响盒子外部的元素。html根元素就是一个BFC
BFC 的触发条件
- html根元素
<html>
- float 不为 none
- 绝对定位元素 也就是 position 为 absolute 和 fixed
- 行内快元素 display 为 inline-block
- display 为 table-cell inline-block flex inline-flex grid inline-grid table-caption(表格标题)
- overflow 不为 visible
BFC 的规则
- 内部的Box会在垂直方向,一个接一个地放置。Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box重叠。
- FC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算。
BFC解决的问题
垂直方向 margin 重叠
.out{
width: 100px;
height: 100px;
background: black;
margin: 20px;
}
<div class='out'></div>
<div class='out'></div>
理论上讲,这两个 div 上下间隙有 40px 因为两个div 的margin都是 20px 加起来就是40px,但是看一下效果图。
这个实际上,只有 20px 的间隙,原因是一个容器内部的所有box会从上往下进行堆叠,并且垂直相邻的距离(即margin)是由各自的margin决定的,在垂直方向上会发生 margin 重叠。解决方案是将两个 div 分属于不同的BFC。
<div class='out'></div>
<div style="overflow: hidden">
<div class='out'></div>
</div>
在其中一个out外面包裹一层div,设置 overflow: hidden 使其变成一个BFC,这样两个out就不会发生margin重叠了。
在看另一外一种margin重叠
.out{
width: 100px;
height: 100px;
background: black;
margin-top: 20px;
}
.inner{
width: 50px;
height: 50px;
background: red;
margin-top: 30px;
}
<div class='out'>
<div class="inner"></div>
</div>
可以看出,整个元素距离顶部的距离是由子元素 inner 的margin-top决定的,因为 inner 的marginTop是大于外部的out的,并且他们都属于 html 跟元素下的BFC,所以margin在垂直方向上会发生重叠,取最大值。
.out{
width: 100px;
height: 100px;
background: black;
margin-top: 20px;
overflow: hidden;
}
给 out 设置 overflow: hidden 让他变成一个 BFC
文本不环绕浮动元素
.float{
float: left;
width: 100px;
height: 100px;
background: red;
color: white;
}
p{
width: 200px;
height: 200px;
background: blue;
color: white;
}
<div class="float">I am a floated box!</div>
<p>I am content inside the container.</p>
现在我们的蓝色区域的文本是围绕着浮动元素进行排列的,如果要实现两栏布局的话有一种办法是让蓝色区域的marginLeft设置为红色区域的宽 + 你想要的边距
p{
width: 200px;
height: 200px;
background: blue;
color: white;
overflow: hidden;
}
将 p 变成BFC
解决包裹浮动元素没有高度的问题
.inner{
float: left;
width: 100px;
height: 100px;
background: red;
}
<div>
<div class='inner'></div>
</div>
一般来说,div 不设置宽高的话,他的宽高会由子元素的宽高给撑起来,但是这边 包裹了一个浮动元素,发现父级元素的高度为 0
同样的设置为BFC