介绍 CSS 中 BFC 的概念、触发条件、布局规则和常见应用场景。

2022-09-15 03:35:27

什么是 BFC

全称是 Block Formatting Context,中文通常翻译为 块级格式化上下文

它是 CSS 中的一个独立布局区域。处于同一个 BFC 中的块级盒子会按照特定规则进行排列,BFC 内部的布局不会直接影响外部元素,外部元素通常也不会影响 BFC 内部的布局。

可以把 BFC 理解为一个独立的容器:容器内部的元素按照自己的规则布局,容器本身再作为一个整体参与外部页面布局。

BFC 的布局规则

  • 同一个 BFC 中,相邻块级盒子的垂直 margin 会发生折叠。
  • 每个盒子的左外边缘会接触包含块的左边缘,即使存在浮动元素也会如此。
  • BFC 区域不会与外部的浮动盒子重叠。
  • 计算 BFC 高度时,内部的浮动元素也会参与计算。

如何创建 BFC

条件示例
根元素<html>
浮动元素float: leftfloat: right
绝对定位元素position: absoluteposition: fixed
overflow 不是 visibleclip 的块元素overflow: hiddenoverflow: autooverflow: scroll
行内块元素display: inline-block
表格相关元素display: table-celldisplay: table-caption
显式创建 BFCdisplay: flow-root
弹性或网格布局中的子元素flex item、grid item
包含布局、内容或绘制隔离的元素contain: layoutcontain: contentcontain: paint

现代 CSS 中,如果只是为了创建一个 BFC,推荐使用:

.container {
    display: flow-root;
}

相比 overflow: hiddendisplay: flow-root 的语义更明确,也不会因为裁剪溢出内容而引入额外副作用。

需要注意的是,overflow: clip 本身不会创建 BFC。如果需要在使用 overflow: clip 的同时创建 BFC,可以配合 display: flow-root

.container {
    overflow: clip;
    display: flow-root;
}

BFC 的常见应用

清除浮动

当父元素内部只有浮动子元素时,父元素可能无法被浮动元素撑开,表现为高度塌陷。


<div class="container">
    <div class="float-box"></div>
</div>
.container {
    display: flow-root;
}

.float-box {
    float: left;
    width: 100px;
    height: 100px;
}

给父元素创建 BFC 后,计算父元素高度时,内部浮动元素也会参与计算。

避免外边距折叠

同一个 BFC 中,相邻块级元素的垂直 margin 可能会发生折叠。

.box-a {
    margin-bottom: 20px;
}

.box-b {
    margin-top: 30px;
}

如果两个元素在同一个 BFC 中,它们之间的实际间距通常是 30px,而不是 50px

如果需要避免某个元素和外部元素发生外边距折叠,可以让它处于新的 BFC 中。

.wrapper {
    display: flow-root;
}

阻止元素被浮动元素覆盖

BFC 区域不会与外部浮动元素重叠,因此可以用来处理浮动元素旁边的自适应布局。


<div class="aside"></div>
<div class="main"></div>
.aside {
    float: left;
    width: 200px;
}

.main {
    display: flow-root;
}

此时 .main 会形成一个新的 BFC,它的区域不会和左侧浮动的 .aside 重叠。