BFC究竟是什么
来看一下MDN上给出的定义:
格式化上下文(Block Formatting Context,BFC)是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
想要直接通过这句定义看明白BFC的意义,或者说作用,那可以说是相当的困难。
我来说一个我的理解:BFC就是一个盒子,这个盒子里的子元素脱离了外面的文本流,只和它的父元素产生关系,并且一定会产生关系,当然我的理解也不是那么容易能直接理解到位,因此我们来深入探究一下BFC。
创建BFC的方法
先不管BFC究竟是什么,以及BFC的作用,我们来看看如何创建BFC,读者也可以先略过这一部分,当彻底明白BFC后,再回过头来看如何创建BFC也无妨。
- 根元素
- 浮动元素(元素的float不是none)
- 绝对定位元素
- display取 inline-block、table-cell、table、flow-root、flex、grid元素
- contain取layout,content,paint
- overflow取不为visible的块元素。
这些方法都能创建出来BFC。
BFC的作用究竟是什么?
毫无疑问这应该是读者最关心的重点,直接下结论:
- 清除内部浮动
- 垂直margin合并
- 创建自适应两栏布局
清除内部浮动
我们都知道浮动布局会脱离文本流,在父元素下的子元素如果设定了float布局,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.flow{
width: 100px;
height: 100px;
background: lightblue;
margin: 100px;
float: left;
}
.father{
}
</style>
<head>
<body>
<div class="father">
<div class="flow"></div>
</div>
</body>
</html>
由于子元素脱离了文本流,那么父元素就没有了子节点,如果说高度没有设定的话,那么就是auto,自动设为了0。
如下图所示
在本例当中,似乎不影响什么,但是在某些时候还是希望float的元素能够撑开父节点的,那么该如何做呢?那就是用BFC,将父节点变为一个BFC盒子,子元素的浮动就会撑开父元素了。
直接在父元素上加如下样式
.father{
overflow: hidden;
}
这样一来,父元素变被撑开了。
垂直magin合并
来看这么一段代码
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.box{
width: 100px;
height: 100px;
background: lightblue;
margin: 100px;
}
</style>
<head>
<body>
<div class="box"></div>
<div class="box"></div>
</body>
</html>
效果如下图所示
能明显看出来,margin只有100了,也就是所谓的外边距被合并了,原因就是
块的上外边距(margin-top)和下外边距(margin-bottom)有时合并(折叠)为单个边距,其大小为单个边距的最大值(或如果它们相等,则仅为其中一个),这种行为称为边距折叠。
如何解决边距折叠这个常见现象呢?就要利用到BFC了。
上文说过,BFC的效果是创建一个盒子,盒子里的子元素只会与父元素产生关系,且这个关系一定会存在。
那也就是说,盒子里的子元素设置边距,那一定是相对于父元素,也就是这个相对于创建出来的BFC盒子的边距,它是不会被边距折叠的。
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.box{
width: 100px;
height: 100px;
background: lightblue;
margin: 100px;
overflow: hidden;
}
</style>
<head>
<body>
<div class="box"></div>
<div style="overflow: auto;">
<div class="box"></div>
</div>
</body>
</html>
如上面的代码所示,我们就是创建了一个新的div包裹了下面的div,这个div我们加了一个样式overflow:auto,聪明的你已经发现了,这个是属于一开始创建BFC的方法之一的,因此我们创建了一个BFC盒子div,在这个div里magin-top是相对于这个盒子所处的位置,因此如下图所示,解决了这个问题:
创建自适应两栏布局
我们经常会有以下的需求,一列图片,一列文字,如果直接采取下面的方式
<!DOCTYPE html>
<html lang="en">
<head>
<style>
div {
width: 200px;
}
img{
float: left ;
}
</style>
<head>
<body>
<div>
<img src="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/e08da34488b114bd4c665ba2fa520a31.svg"></img>
<p class="info">这边是我们需要的文字排版</p>
</div>
</body>
</html>
会是一个环绕图片型的文字排版,原因是float脱离了文本流,p占据了整个行,那么当超过width时候自然会放到图片下面了。
我们如果要写一个两栏布局的话,就需要让p元素不影响浮动元素。
因此将p写为BFC元素。
添加样式:
p{overflow: auto}
两栏布局也就成功了。
总结
BFC随着flex布局的流行,自然而然的会使用的相对少了些,因为当你设置flex时候会自动有BFC,以及flex布局的强大功能。但是如果我们知道了BFC的原理,以及如何创建,那么在某些时候就能够解释CSS的奇怪现象了。