8.2 CSS 块排版上下文(Block Formatting Context)

用来确定块级元素的格式化

BFC(Block Formatting Contexts)即块排版上下文,也可称为块格式化上下文。Block Formatting Contexts就是页面上的一个隔离的渲染区域,容器里面的子元素不会在布局上影响到外面的元素,反之也是如此。

BFC布局规则

  1. 内部的Box会在垂直方向,一个接一个地放置。
  2. Box垂直方向的距离由margin决定。同属一个BFC的相邻块级盒子的垂直margin会发生合并(Collapse)
  3. 每个元素盒子的左外边缘(即Margin box的左边)和包含块的左边缘(即Border box的左边)相接触(对于从右往左的排版则相反,是右边接触)。即使存在浮动也是如此。
  4. BFC的区域不会与float box重叠。
  5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  6. 计算BFC的高度时,浮动元素也参与计算。

何时会生成BFC

  • 根元素,即html标签元素(有些浏览器下是body标签元素)
  • float属性不为none
  • position为absolute或fixed
  • display为inline-block, table-cell, table-caption, flex, inline-flex
  • overflow不为visible

注意:inline-block归属inline-level box,但并不是inline box,这类box被称为原子内联级盒子(atomic inline-level box),被当作一个不透明的单个盒子来参与到IFC中。 它其实是一个披着inline外衣的block容器,在外部以inline-level box的身份参与IFC(并不会生成一个IFC),其内部被当作一个block box来格式化,因此将生成一个BFC来约束其内部元素的排版。参考阅读:W3内联级别规范

BFC有什么用途

例子1:使用BFC构建自适应两栏布局

  • aside浮动元素生成一个BFC,按规则3,其左外边缘和wrap的左边缘对齐。
  • main元素通过overflow:hidden生成一个BFC,按规则5,它将不和aside浮动元素发生重叠。(参考阅读:和浮动元素相邻的BFC

这样就生成了一个简单的两栏布局,且main部分自动和sidebar分开,不需要设定固定的位移值。

例子2:清除内部浮动

  • 对wrap使用overflow:hidden,将触发创建一个新的BFC,而BFC在计算高度时会把float元素计算在内。其效果就等同于清除了内部浮动。
  • 如果去掉wrap元素的overflow:hidden,wrap内部高度为0。因为默认情况下浮动元素不计入父元素行高。(参考阅读:CSS 浮动(float)

例子3:防止垂直方向的 margin 合并

  • BFC内部块元素的垂直margin会发生合并(也叫折叠collapse),这在前面的CSS外边距章节讲解过。
  • 不同属于一个BFC的块元素垂直margin不会发生合并,所以通过给上面例子中的p元素添加一个BFC的wrap元素,可以避免上述的合并。

总之,我们只要记住:

BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之亦然。

当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过收缩自动避让开浮动块。当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin合并也是这种渲染独立性的体现。