BFC到底是什么

83 阅读3分钟

1. 什么是FC,什么是BFC

  • FC 的全称是Formatting Context(格式化上下文),元素在标准流里面都是属于一个FC的:

  • 块级元素的布局属于Block Formatting Context(BFC)

    • 也就是block level box都是在BFC中布局的
  • 行内级元素的布局属于Inline Formatting Context(IFC)

    • 而inline level box都是在IFC中布局的

2. 那么在什么情况下会创建BFC呢

  • 根元素()
  • 浮动元素(元素的 float 不是 none)
  • 绝对定位元素(元素的 position 为 absolute 或 fixed)
  • 行内块元素(元素的 display 为 inline-block)
  • display 值为 flow-root 的元素
  • 表格单元格(元素的 display 为 table-cell,HTML表格单元格默认为该值),表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
  • 匿名表格单元格元素(元素的 display 为 table、table-row、table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table)
  • overflow 计算值(Computed)不为 visible 的块级元素
  • 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
  • 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)

3. BFC有什么作用呢

官方对BFC作用的描述:

  1. 在块格式上下文中,盒子从包含块的顶部开始,一个接一个地垂直排列。两个相邻框之间的垂直距离由“margin”属性决定。块格式上下文折叠中相邻块级框之间的垂直边距。
  2. 在块格式上下文中,每个框的左外缘与包含块的左边缘相连(对于从右到左的格式,是右边缘相连)。即使存在浮动(尽管一个盒子的行盒可能会因为浮动而收缩),除非盒子建立了一个新的块格式化上下文(在这种情况下,盒子本身可能会因为浮动而变窄)。

简单概述为:

  • 在BFC中,box会在垂直方向上一个挨着一个的排布
  • 垂直方向的间距由margin属性决定
  • 在同一个BFC中,相邻两个box之间的margin会折叠(collapse)
  • 在BFC中,每个元素的左边缘是紧挨着包含块的左边缘的

4. 我们来看两个问题

BFC1.jpg margin折叠.png

问题一:为什么box1和box2各设置了margin为100px,为什么实际的margin-top之间只有100px

BFC2.jpg code.jpg

问题二:由问题一我们可以看到正常情况下,box的高度也是可以显示的,因为设置了400px,但是为什么设置了浮动之后box的高度就塌陷了呢

5. 那么BFC的作用就很明显了

  • 解决margin的折叠问题
  • 解决浮动高度塌陷问题

6. BFC是怎样解决折叠问题的

  • 在同一个BFC中,相邻两个box之间的 margin 会折叠(collapse)
    • 那么如果我们让两个box是不同的BFC呢?那么就可以解决折叠问题。

7. 解决浮动高度塌陷的方案

  • 网上有很多说法,BFC可以解决浮动高度塌陷,可以实现清除浮动的效果。

    • 但是从来没有给过BFC可以解决高度塌陷的原理或者权威的文档说明;
    • 他们也压根没有办法解释,为什么可以解决浮动高度的塌陷问题,但是不能解决绝对定位元素的高度塌陷问题呢?
  • 事实上,BFC解决高度塌陷需要满足两个条件:

    • 浮动元素的父元素触发BFC,形成独立的块级格式化上下文(Block Formatting Context);
    • 浮动元素的父元素的高度是auto的;
  • BFC的高度是auto的情况下,是如下方法计算高度的

    1. 如果只有inline-level,是行高的顶部和底部的距离;
    2. 如果有block-level,是由最底层的块上边缘和最底层块盒子的下边缘之间的距离
    3. 如果有绝对定位元素,将被忽略;
    4. 如果有浮动元素,那么会增加高度以包含这些浮动元素的下边缘。