BFC?到底是个啥?

171 阅读3分钟

好多人讲BFC,看了之后感觉还是一头雾水,因此我大战MDN文档,找到了我想要的答案,以前没有写掘金的习惯,现在分享给大家。

BFC,block formatting context,块级格式化上下文,啥意思呢?我把他翻译成:块级元素的布局空间,我觉得可以理解成类似于作用域这种概念,就是说这个空间里的元素的布局排布,归我管!

其实还有另外一个东西:IFC,inline formatting context,我们应该能猜出来,没错,他就是行内元素的布局空间,不过这个东西一般很少讨论,我们还说回BFC。

你看啊,BFC和IFC都有FC两个字母,FC是formatting context,说白了就是布局空间,就是“布局作用域”,我们可以理解成一个FC就是一个“国家”,这个“国家”内部怎么布局,内部自己管辖,不受外界影响,叫我的地盘我做主

在我的地盘,就要遵循我的布局规则,那么BFC的规则是什么呢?先记住主要的三点就行了:

  1. 盒子在垂直方向上依次排布。
  2. 垂直方向上的盒子间距由margin决定
  3. 在同一个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当成一个神秘的东西,只要知道它咋回事,怎么利用就好了。

希望能帮到大家,欢迎讨论。