CSS 的 BFC 原理

1.常见定位方案

有三种:

  • 普通流 (normal flow): 元素按HTML文档中的位置自上而下布局。
  • 浮动 (float):先按照普通流,然后根据浮动方向偏移脱离普通流。
  • 绝对定位 (absolute positioning):整体脱离普通流,不影响兄弟元素,位置由坐标绝地。

2.BFC 概念

Block Formatting context(块级格式上下文) 是 W3C 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定子元素如何定位,它和其他元素的关系和相互作用。它属于上述定位方案的普通流。BFC元素可理解为一个封闭的盒子,内部的元素无论怎么变,都不会影响到外部。

3.BFC 触发

只要符合一条件就触发:(body,float, position, display, overflow)

  • 根元素或其它包含它的元素
  • 浮动 (元素 float 不为 none)
  • 绝对定位元素 (元素 position 为 absolute 或 fixed)
  • 内联块 inline-blocks (元素 display: inline-block)
  • 表格单元格 (元素 display: table-cell,表格单元格默认属性)
  • 表格标题 (元素 display: table-caption, 表格标题默认属性)
  • 被声明为块级的元素 overflow 不为 visible
  • 弹性盒 flex boxes (元素 display: flex 或 inline-flex)

4.BFC 作用

  1. 垂直margin合并

相邻的两个盒子的外边距折叠:

  • 两正数,取大的值。
  • 两负数,取绝对值大的值。
  • 一正一负,两者的相加的和。
  1. 清除内部浮动

由于容器内元素浮动,脱离了文档流,所以容器只剩下 2px 的边距高度。如果使触发容器的 BFC,那么容器将会包裹着浮动元素(给父元素设置overflow:hidden)。

  1. 创建自适应两栏布局

阻止元素被浮动元素覆盖(第二个元素中加入 overflow: hidden)。左边的宽度固定,右边的内容自适应宽度。

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

Reference:
https://www.w3.org/html/ig/zh/wiki/CSS2/visuren#block-formatting
https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context