BFC 块格式化上下文

491 阅读3分钟

块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视化 CSS 渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。

具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。

通俗一点来讲,可以把 BFC 理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。

在一个块格式化上下文中,每个盒的 left 外边(left outer edge)挨着包含块的 left 边(对于从右向左的格式化,right 边挨着)。即使存在浮动(尽管一个盒的行盒可能会因为浮动收缩),这也成立。除非该盒建立了一个新的块格式化上下文。(这种情况下,该盒自身可能会因为浮动变窄)

触发 BFC

下列方式会创建块格式化上下文:

  • 根元素或包含根元素的元素;
  • 浮动元素(元素的 float 不是 none);
  • 绝对定位元素(元素的 positionabsolutefixed);
  • 行内块元素(元素的 displayinline-block);
  • 表格单元格(元素的 displaytable-cell,HTML 表格单元格默认为该值);
  • 表格标题(元素的 displaytable-caption,HTML 表格标题默认为该值);
  • 匿名表格单元格元素(元素的 displaytabletable-rowtable-row-grouptable-header-grouptable-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table);
  • overflow 值不为 visible 的块元素;
  • display 值为 flow-root 的元素;(无任何副作用)
  • contain 值为 layoutcontentstrict 的元素;
  • 弹性元素(displayflexinline-flex 元素的直接子元素);
  • 网格元素(displaygridinline-grid 元素的直接子元素);
  • 多列容器(元素的 column-countcolumn-width 不为 auto,包括 column-count 为 1);
  • column-spanall 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中。

应用 BFC

让浮动内容和周围的内容等高

由于层叠顺序,会使得浮动元素与周围的内容不等高,造成 bug:

应用 BFC 让浮动内容和周围的内容等高。
html 代码如下:

<div class="parent">
  <div class="child"></div>
</div>

css 代码如下:

.parent {
  border: 2px solid black;
  display: flow-root;  // 触发 BFC
}
.child {
  height: 100px;
  width: 100px;
  background: red;
  float: left;
}

阻止元素被浮动元素覆盖

由于层叠顺序,使得浮动元素的 z 轴在文本内容和块级元素之间,造成浮动元素覆盖块级元素却不覆盖文本内容的 bug。(当然,浮动属性被设计的原因便是需要文字环绕在被浮动的图片周围,给论文排版以便利)

应用 BFC 阻止元素被浮动元素覆盖,将两个元素彻底分离开。
html 代码如下:

<div class="left">左</div>
<div class="right">右</div>

css 代码如下:

.left {
  border: 2px solid red;
  height: 200px;
  width: 100px;
  float: left;
}
.right {
  border: 2px solid green;
  height: 200px;
  background: green;
  display: flow-root;  // 触发 BFC
}

外边距塌陷

在一个块格式化上下文中,盒在竖直方向一个接一个地放置,从包含块的顶部开始。两个兄弟盒之间的竖直距离由 margin 属性决定,同一个块格式化上下文中的相邻块级盒之间的竖直 margin 会合并。