一、BFC 定义
BFC(Block formatting context)直译为"块级格式化上下文"。
Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。
BFC
是一个完全独立的渲染区域,它规定了内部的Block-level Box如何布局,让空间里的子元素布局不会影响到外面的布局,也不会受到外界的影响。
二、 BFC的布局规则
1.内部的Box会在垂直方向,一个接一个地放置
2.Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠(传说中的margin塌陷)
3.BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
4.BFC的区域不会与float box重叠
5.计算BFC的高度时,浮动元素也参与计算
三、如何创建BFC
1、float的值left, right。
2、position的值absolute, fixed。
3、display的值是inline-block、flex、inline-flex、table-cell、table-caption
4、overflow:hidden5、根元素,也就是html根标签会触发bfc
四、BFC的作用
1.解决margin塌陷问题
<style>
*{
margin: 0;
padding: 0;
}
p {
color: #f55;
background: blue;
width: 200px;
line-height: 100px;
text-align:center;
margin: 30px;
}
</style>
<body>
<p>看看我的 margin是多少</p>
<p>看看我的 margin是多少</p>
</body>
可以看到上面我们为两个盒子的margin外边距设置的都是30px,可结果显示两个盒子之间只有30px的距离,这就导致了margin塌陷问题,这时margin边距的结果为最大值,而不是和,为了解决此问题可以使用BFC规则(为元素包裹一个盒子形成一个完全独立的空间,做到里面元素不受外面布局影响),或者简单粗暴方法一个设置margin,一个设置padding。
因为属于同一个BFC的两个相邻的Box会发生margin重叠,所以我们可以设置,两个不同的BFC,也就是我们可以让把第二个p用div包起来,然后激活它使其成为一个BFC
<style>
*{
margin: 0;
padding: 0;
}
p {
color: #f55;
background: blue;
width: 200px;
line-height: 100px;
text-align:center;
margin: 30px;
}
div {
display: inline-block;
}
</style>
<body>
<p>看看我的 margin是多少</p>
<div><p>看看我的 margin是多少</p></div>
</body>
2.清除浮动,防止元素塌陷
可以看到父元素没设置高度,子元素设置浮动时,父元素的高度没有被撑开。如下图父元素背景色看不到,上下border合并。
这个时候我们根据最后一条:
- 计算BFC的高度时,浮动元素也参与计算。
给父节点激活BFC,给父元素设置一个overflow:hidden属性后,就可以起到清除浮动的作用。
<style>
.wrap {
background: lime;
border: 20px solid red;
// overflow: hidden;
}
.item{
float: left;
background: lightsalmon;
height: 100px;
width: 150px;
margin: 10px;
}
</style>
<body>
<div class="wrap">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
3.两栏布局,防止出现文字环绕效果
有两个同级的div元素,前面div的设置了左浮动,会覆盖住后面的元素。在这里可以看到当left设置为浮动后,会浮动在right的上面,看起来像是left被right环绕包裹起来的感觉;
又因为:
- BFC的区域不会与float box重叠。
所以为right添加一个包裹div并设置overflow属性,使其成为一个BFC区域,这样就可以避免出现文字环绕效果,并且可以实现自动实现两栏布局效果。
<style>
*{
margin: 0;
padding: 0;
}
body {
width: 100%;
position: relative;
}
.left {
width: 100px;
height: 150px;
float: left;
background: rgb(139, 214, 78);
text-align: center;
line-height: 150px;
font-size: 20px;
}
.right {
width: 400px;
height: 300px;
background: rgb(170, 54, 236);
text-align: center;
line-height: 300px;
font-size: 40px;
/* overflow: hidden; */
}
</style>
<body>
<div class="left">LEFT</div>
<div class="right">RIGHT</div>
</body>
[参考文章]