背景介绍

在解释 BFC 之前,先说一下文档流。我们常说的文档流其实分为定位流、浮动流和普通流三种。而普通流其实就是指 BFC 中的 FC。FC 是 formatting context 的首字母缩写,直译过来是格式化上下文,它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。常见的 FC 有 BFC、IFC,还有 GFC 和 FFC。BFC 是 block formatting context。

什么是BFC

  1. BFC(Block formatting context)直译为”块级格式化上下文”。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
  2. Block-level box:display 属性为 block, list-item(为元素内容生成一个块型盒,随后再生成一个列表型的行内盒), table(转化为表格) 的元素,会生成 block-level box。并且参与 block fomatting context;

怎样才能形成BFC

  1. 根元素或包含根元素的元素,即body根元素
  2. 浮动元素,即float属性值不为none(元素的position为absolute或fixed)
  3. 行内块元素(元素的display为inline-block)
  4. 表格单元格(元素的display为table-cell,HTML表格单元格默认为该值)
  5. 表格标题(元素的display为table-caption,HTML表格标题默认为该值)
  6. 匿名表格单元格元素(或者元素的display为table、table-row、table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或inline-table)
  7. overflow的值不为visible的元素
  8. display值为flow-root`的元素
  9. contain值为layout、content或strict`的元素
  10. 弹性元素(display为flex或inline-flex元素的直接子元素)
  11. 网格元素(display为grid或inline-grid元素的直接子元素)
  12. 多列容器(元素的colunm-count或column-width不为auto,包括column-count为1)
  13. column-span为all的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器当中

BFC的作用

  1. 包含浮动元素 (清除浮动) BFC 会根据子元素的情况自适高度,这个特性是对父元素使用 overflow:hidden/auto/scroll、 float:left/right 样式可以闭合浮动(清除浮动)的
  2. 不被浮动元素覆盖 浮动元素会无视兄弟元素的存在, 覆盖在兄弟元素的上面, 为该兄弟元素创建 BFC 后可以阻止这种情况的出现

BFC的规则

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

BFC常见问题

  1. 元素重叠
  2. 浮动坍塌的问题
  3. margin 重叠

解决方案

  1. 图片默认是 inline 水平的,而 vertical-align 对块状水平的元素无感。因此,我们只要让图片 display 水平为 block 就可以了,我们可以直接设置 display 或者浮动、绝对定位等
  2. BFC 可以包含浮动的元素 这也正是上面使用 overflow: hidden 与 overflow: auto 方法闭合浮动的原理,使用 overflow: hidden 或 overflow: auto 触发浮动元素父元素的 BFC 特性,从而可以包含浮动元素,闭合浮动。W3C 的原文是 “’Auto’ heights for block formatting context roots”,也就是 BFC 会根据子元素的情况自动适应高度,即使其子元素中包括浮动元素

总结

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

  2. 因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。