好多人讲BFC,看了之后感觉还是一头雾水,因此我大战MDN文档,找到了我想要的答案,以前没有写掘金的习惯,现在分享给大家。
BFC,block formatting context,块级格式化上下文,啥意思呢?我把他翻译成:块级元素的布局空间,我觉得可以理解成类似于作用域这种概念,就是说这个空间里的元素的布局排布,归我管!
其实还有另外一个东西:IFC,inline formatting context,我们应该能猜出来,没错,他就是行内元素的布局空间,不过这个东西一般很少讨论,我们还说回BFC。
你看啊,BFC和IFC都有FC两个字母,FC是formatting context,说白了就是布局空间,就是“布局作用域”,我们可以理解成一个FC就是一个“国家”,这个“国家”内部怎么布局,内部自己管辖,不受外界影响,叫我的地盘我做主!
在我的地盘,就要遵循我的布局规则,那么BFC的规则是什么呢?先记住主要的三点就行了:
- 盒子在垂直方向上依次排布。
- 垂直方向上的盒子间距由margin决定
- 在同一个BFC中,相邻盒子的margin会合并(或者说折叠?)
也就是说在BFC中,遵循这样的布局法则。记住哦,在第三点上我加了“在同一个BFC中”这句话,很重要哦!因为我们马上要讲到margin的合并问题。
margin的合并问题,就是两个盒子,上面盒子的下边距margin-bottom会和下面盒子的上边距margin-top合并,最终只保留其中一个margin(较大的那个)。
为什么会这样?因为BFC的布局就是这个法则: “在同一个BFC中,相邻盒子的margin会合并”,换句话说,margin合并问题就是BFC的规则导致的,那么怎么解决?有一大堆方法,我不写了,以前看的迷迷糊糊不知道为啥那样就行,后来明白了,既然同一个BFC中的上下margin会合并,那让他们处于不同的BFC中不就好了!
对,没错,所有解决margin合并的方法里,背后的本质都是一个,就是让他们处于不同的BFC中,让其中一方处于一个独立的BFC中就好了。嘻嘻,这样就不用记了吧。
那么怎么触发新的BFC呢?
- 根元素
- 浮动元素:float不是none
- 弹性布局:display:flex、inline-flex
- 网格布局:display:grid、inline-grid
- 行内块元素:display:inline-block
- diplay:flow-root
- 表格布局:display:table-cell、display:table
- 独立布局:overflow不是visible的
- 定位布局:position不是static,
以上情况,浏览器为其会创建BFC。
利用BFC,我们还可以解决另外一个问题:浮动元素的高度塌陷。
比如说,一个盒子里放俩div,宽高都是一百,都设置为float:left,这时候父容器就没高度了。
怎么解决?可以用清除浮动解决,另外就是可以用利用BFC的规则来解决,BFC里还有一个法则,就是:当BFC的父容器heigh为auto时,会增加高度来包裹浮动元素的下边缘。因此只需要给其父容器设置:height:auto;overflow:auto;就可以了。
最后总结:每个FC就是一个布局作用域,有BFC,有IFC,BFC里遵循BFC的规则,IFC遵循IFC的规则。我们不用把BFC当成一个神秘的东西,只要知道它咋回事,怎么利用就好了。
希望能帮到大家,欢迎讨论。