BFC概念
BFC(Block formatting context)直译为“块级格式化上下文”,只有块级的盒子参与,内部规定了块级盒子如何布局。
BFC是一个独立的布局环境,其中的元素布局是不受外界的影响。
display属性为block、table、list-item的元素默认会产生BFC。也可以手动创建,如果将一个div(默认为块级元素,即本身拥有BFC)设置为inline-block,会产生一个新的BFC。
如何创建BFC
- float属性不为none
- position属性为absolute或fixed
- display为inline-box、flex、inline-flex、table-cell
- overflow不为visible
BFC布局特性
- 在BFC中,盒子从顶端开始垂直往下排列
- 盒子垂直方向的间距由margin决定,属于同一个BFC的两个相邻的盒子margin会发生重叠
- 在BFC中,每一个盒子的左外边缘(
margin-left
)会触碰到容器的左内边缘(border-left
) - BFC的区域不会与浮动盒子产生交集,而是紧贴浮动边缘
- 在计算BFC的高度时,也会检测浮动或定位的盒子高度
BFC的作用
清除浮动
只要把父元素设置为BFC,就可以清除子元素的浮动了,如:常使用overflow:hidden
1
2
3<div>
<p>1</p>
</div>1
2
3
4
5
6div{}
p {
width: 200px;
line-height: 100px;
text-align: center;
}我们可以给div设置以下这些样式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16div{
/*推荐第一种*/
overflow: hidden;
overflow: auto;
display: flex;
/* 可以解决p的浮动问题,但同时增加了div自己的浮动问题 */
float: left;
/* 可以解决p的浮动问题,但是同时让div没有宽度,只是被p给撑起来了 */
display: inline-block;
display: table-cell;
display: inline-flex;
position: absolute;
position: fixed;
}解决外边距合并问题
只要创建不属于同一个BFC,外边距就不会发生合并,如:1
2<p>1</p>
<p class="p2">2</p>1
2
3
4
5
6
7p {
width: 200px;
line-height: 100px;
text-align: center;
background-color: #f00;
margin: 30px;
}有两个p(块级元素,本身拥有同一个BFC),都设置
marign
时,默认p1的marign-bottom
和p2的margin-top
会发生合并,只表现出一个30px的间距。
如何解决呢?可以让p2产生一个新的BFC,只要不p1、p2不属于同一个BFC,margin
就不会发生合并。1
2
3
4
5
6
7.p2{
float: left;
display: inline-block;
display: inline-flex;
position: absolute;
position: fixed;
}以上这些属性都可以直接作用于某个盒子本身,然后产生一个新的BFC。当然也可以有更多的办法:
1
2
3
4<p>1</p>
<div>
<p>2</p>
</div>使用div包裹p2,然后给div这个父级设置样式,这个时候就有了更多的选择,任选一种即可。
1
2
3
4
5
6
7
8
9
10
11
12div{
float: left;
display: inline-block;
display: inline-flex;
position: absolute;
position: fixed;
/* 除了上面这些,还可添加这些作用于父级的样式 */
overflow: hidden;
overflow: auto;
display: flex;
display: table-cell;
}自适应两列布局
根据特性3: 每一个盒子的左外边缘(marigin)会触碰容器的左内边缘(border-left),即使是浮动元素。1
2<div class="left">LEFT</div>
<div class="right">RIGHT</div>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20body{
border: 5px solid #f00;
}
.left {
width: 100px;
height: 150px;
float: left;
background: #0f0;
text-align: center;
line-height: 150px;
font-size: 20px;
margin: 5px;
}
.right {
height: 300px;
background: #00f;
text-align: center;
line-height: 300px;
font-size: 40px;
}从下图可以看出:left的margin-left外边缘(蓝色margin 5px左侧)和父级容器(body)的border-left(红色border 5px内侧)内边相触碰。
再根据特性4:BFC的区域不会与浮动盒子产生交集,而是紧贴浮动边缘。
让right单独成一个BFC,添加样式:1
2
3.right{
overflow: hidden;
}这样就实现两列布局了,并且right布局可以自适应。