背景介绍
在解释 BFC 之前,先说一下文档流。我们常说的文档流其实分为定位流、浮动流和普通流三种。而普通流其实就是指 BFC 中的 FC。FC 是 formatting context 的首字母缩写,直译过来是格式化上下文,它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。常见的 FC 有 BFC、IFC,还有 GFC 和 FFC。BFC 是 block formatting context。
什么是BFC
- BFC(Block formatting context)直译为”块级格式化上下文”。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
- Block-level box:display 属性为 block, list-item(为元素内容生成一个块型盒,随后再生成一个列表型的行内盒), table(转化为表格) 的元素,会生成 block-level box。并且参与 block fomatting context;
怎样才能形成BFC
- 根元素或包含根元素的元素,即body根元素
- 浮动元素,即float属性值不为none(元素的position为absolute或fixed)
- 行内块元素(元素的display为inline-block)
- 表格单元格(元素的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的值不为visible的元素
- display值为flow-root`的元素
- contain值为layout、content或strict`的元素
- 弹性元素(display为flex或inline-flex元素的直接子元素)
- 网格元素(display为grid或inline-grid元素的直接子元素)
- 多列容器(元素的colunm-count或column-width不为auto,包括column-count为1)
- column-span为all的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器当中
BFC的作用
- 包含浮动元素 (清除浮动) BFC 会根据子元素的情况自适高度,这个特性是对父元素使用 overflow:hidden/auto/scroll、 float:left/right 样式可以闭合浮动(清除浮动)的
- 不被浮动元素覆盖 浮动元素会无视兄弟元素的存在, 覆盖在兄弟元素的上面, 为该兄弟元素创建 BFC 后可以阻止这种情况的出现
BFC的规则
- 内部的 Box 会在垂直方向,从顶部开始一个接一个地放置
- Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 上下会发生重叠
- 每个元素的 margin box 的左边, 与包含块 border box 的左边相接触 (对于从左往右的格式化,否则相反)。即使存在浮动也是如此
- BFC 的区域不会与 float box 重叠
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算
BFC常见问题
- 元素重叠
- 浮动坍塌的问题
- margin 重叠
解决方案
- 图片默认是 inline 水平的,而 vertical-align 对块状水平的元素无感。因此,我们只要让图片 display 水平为 block 就可以了,我们可以直接设置 display 或者浮动、绝对定位等
- BFC 可以包含浮动的元素 这也正是上面使用 overflow: hidden 与 overflow: auto 方法闭合浮动的原理,使用 overflow: hidden 或 overflow: auto 触发浮动元素父元素的 BFC 特性,从而可以包含浮动元素,闭合浮动。W3C 的原文是 “’Auto’ heights for block formatting context roots”,也就是 BFC 会根据子元素的情况自动适应高度,即使其子元素中包括浮动元素
总结
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。