定义:
BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
BFC布局规则:
- 内部的Box会在垂直方向,一个接一个地放置。
- Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
- 在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘),即使存在浮动也是如此。
- BFC的区域不会与float box重叠。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算。
如何触发BFC(哪些元素会生成BFC?):
只要元素满足下面任一条件即可触发 BFC 特性:
- body 根元素
- 浮动元素:float 除 none 以外的值
- 绝对定位元素:position (absolute、fixed)
- display 为 inline-block、table-cells、flex
- overflow 除了 visible 以外的值 (hidden、auto、scroll)
BFC特性及应用:
1. 同一个 BFC 下外边距margin会发生重叠
<style>
div{
width: 100px;
height: 100px;
background: lightblue;
margin: 100px;
}
</style>
<body>
<div></div>
<div></div>
</body>
从效果上看,因为两个 div 元素都处于同一个 BFC 容器下 (这里指 body 元素) 所以第一个 div 的下边距和第二个 div 的上边距发生了重叠,所以两个盒子之间距离只有 100px,而不是 200px。
首先这不是 CSS 的 bug,我们可以理解为一种规范,如果想要避免外边距的重叠,可以将其放在不同的 BFC 容器
.container {
overflow: hidden;
}
.one,.two{
width: 100px;
height: 100px;
background: lightblue;
margin: 100px;
}
<div class="container">
<div class="one"></div>
</div>
<div class="container">
<div class="two"></div>
</div>
2.解决浮动塌陷问题(BFC 可以包含浮动的元素——清除浮动)
示例代码如下:
<style>
.parent {
border: 2px solid #428bca;
}
.child {
width: 100px;
height: 100px;
float: left;
background: #3BD49E;
}
</style>
<div class="parent">
<div class="child"></div>
</div>
上述代码的效果是这样,可能和你想的有一些出入
这其中的原理是这样:
• 如果父元素只包含浮动元素,且父元素未设置高度和宽度的时候,那么它的高度就会塌缩为零。
• 如果父元素不包含任何的可见背景,这个问题会很难被注意到,但是这是一个很重要的问题,上面的代码就是一个典型的例子。
为解决浮动塌陷的问题,也可以用 BFC 来解决(参见第四条约束规则)
为其父元素创建 BFC
修改父元素的 CSS 代码:
.parent {
border: 2px solid #428bca;
overflow: auto;/*overflow: hidden;*/
}
修改后就可以解决这个问题。如图所示
3.BFC 可以阻止元素被浮动元素覆盖(自适应两栏布局)
<div style="height: 100px;width: 100px;float: left;background: lightblue">
我是一个左浮动的元素
</div>
<div style="width: 200px; height: 200px;background: #eee">
我是一个没有设置浮动,也没有触发 BFC 元素, width: 200px; height:200px; background: #eee;
</div>
这时候其实第二个元素有部分被浮动元素所覆盖,(但是文本信息不会被浮动元素所覆盖) 如果想避免元素被覆盖,可触第二个元素的 BFC 特性,在第二个元素中加入 overflow: hidden,就会变成:
注:这个方法可以用来实现两列自适应布局,效果不错,这时候左边的宽度固定,右边的内容自适应宽度(去掉上面右边内容的宽度)。
也可以是3列:
<style>
html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
.left{
background:pink;
float: left;
width:180px;
height:200px;
}
.center{
background:lightyellow;
overflow:hidden;
height:200px;
}
.right{
background: lightblue;
width:180px;
height:200px;
float:right;
}
</style>
<div class="container">
<div class="right">right</div>
<div class="left">left</div>
<div class="center">center</div>
</div>
效果图如下: