Skip to content

BFC(块级格式化上下文) ​

BFC(Block Formatting Context)是 CSS 布局中一块「独立的渲染区域」,区域内的元素按一套封闭规则排版,与外部相互隔离。理解 BFC,本质是理解浏览器「如何划分布局边界」,从而优雅解决外边距折叠、浮动高度塌陷、两栏自适应这三类高频布局问题。

导航目录 ​

一、原理篇 ​

二、实战篇 ​

概念定义 ​

BFC(Block Formatting Context,块级格式化上下文) 可以理解为:浏览器在页面中划出的一块独立布局/渲染区域。在这个区域内,块级元素按一套相对「封闭」的规则排版,从而让区域内外的布局影响尽量隔离。

核心概念:BFC 的两大价值

  • 隔离布局影响:把一些布局规则(例如外边距折叠、与浮动的关系)限制在 BFC 内部,内外互不干扰。
  • 让容器「包住」内容:开启 BFC 后,父容器在计算高度时会把内部浮动子元素也纳入,从而避免高度塌陷。

一句话记忆:BFC 是一个自成一体的「布局沙箱」。

触发条件 ​

满足以下任一条件,元素就会创建一个 BFC。下表按使用频率整理常见触发方式:

CSS 属性触发值说明
overflowhidden / auto / scroll(非 visible)最常用,副作用小
float非 none(left / right)元素自身也会浮动
positionabsolute / fixed元素会脱离文档流
displayinline-block / table-cell / table-caption / flow-rootflow-root 是专为触发 BFC 设计的值,无副作用

首选 overflow: hidden 还是 display: flow-root?

overflow: hidden 虽最常用,但可能意外裁剪掉需要溢出显示的内容(如阴影、下拉菜单)。若只想触发 BFC 而不引入任何副作用,优先使用 display: flow-root——它是 CSS 官方为「创建 BFC」这一目的新增的专用值。

关键特性 ​

BFC 的细节规则很多,抓住与日常布局最相关的 4 点即可:

  1. 内部块级盒子按文档流在垂直方向依次排列
  2. 同一 BFC 内相邻块的垂直外边距会发生折叠(margin collapse)——不同 BFC 之间则不会
  3. BFC 区域不会与浮动元素重叠(用于两栏/自适应布局)
  4. 计算 BFC 高度时会把内部浮动元素也纳入计算(用于「清除浮动」的替代方案)

用一张图理解「隔离」

BFC 的核心是「边界隔离」——把内部布局规则封闭在容器内,与外部世界互不影响:

text
外部文档流
    │
    ▼
BFC(独立布局区域)───────┐
    ├── ① 内部块垂直排列   │
    ├── ② 内部相邻块 margin 折叠
    ├── ③ 不与外部浮动重叠  │ 边界隔离
    └── ④ 高度包含内部浮动  │  互不影响
                           │
外部文档流 ────────────────┘

应用场景(附示例) ​

场景 1:解决垂直外边距折叠(margin collapse) ​

当两个块级元素上下相邻时,一个 margin-bottom + 另一个 margin-top 会发生外边距折叠,最终间距取两者中的较大值(而非相加)。让其中一侧进入新的 BFC,即可把折叠限制在各自的 BFC 内。

html
<div class="wrap">
  <div class="a"></div>
</div>
<div class="b"></div>
css
.a {
  height: 40px;
  margin-bottom: 30px;
  background: #ddd;
}
.b {
  height: 40px;
  margin-top: 30px;
  background: #bbb;
}

/* 关键:让 .a 所在容器创建 BFC,避免与外部发生折叠 */
.wrap {
  overflow: hidden;
}

要点

外边距折叠只发生在「同一个 BFC」内的相邻块之间;通过创建新的 BFC,可把折叠影响隔离在容器内部。

场景 2:清除浮动(让父元素包住浮动子元素) ​

经典问题:子元素浮动后脱离普通文档流,父元素高度塌陷。让父元素创建 BFC,其高度就会把内部浮动元素算进去。

html
<div class="parent">
  <div class="left"></div>
  <div class="right"></div>
</div>
css
.left,
.right {
  float: left;
  width: 50%;
  height: 60px;
}
.left {
  background: #ddd;
}
.right {
  background: #bbb;
}

/* 关键:父元素创建 BFC,高度会把内部浮动也算进去 */
.parent {
  overflow: auto;
}

overflow 取值的取舍

overflow: hidden 可能裁剪溢出内容;需要滚动条时用 overflow: auto;若既不想裁剪也不想引入滚动条,最佳选择是 display: flow-root。

场景 3:两栏布局中,右侧不与左侧浮动重叠 ​

左侧浮动固定宽度,右侧自适应时,让右侧创建 BFC,它就会自动避开浮动区域。

html
<div class="layout">
  <div class="aside"></div>
  <div class="main"></div>
</div>
css
.aside {
  float: left;
  width: 200px;
  height: 80px;
  background: #ddd;
}

/* 关键:创建 BFC(任选一种方式) */
.main {
  overflow: hidden;
  height: 80px;
  background: #bbb;
}

要点

BFC 不会与浮动区域重叠,因此右侧能自然「贴着」左侧浮动元素,实现自适应两栏布局。

你应该记住的结论 ​

一图流总结

  • 是什么:BFC 是一个独立的布局上下文(布局沙箱),用来隔离布局影响。
  • 怎么触发:最推荐 display: flow-root(无副作用),其次 overflow: hidden/auto、float、position: absolute/fixed。
  • 解决什么:三类高频问题——① 外边距折叠、② 父元素包住浮动(高度塌陷)、③ 两栏布局避开浮动。

结语:理解「边界」比背诵规则更重要

BFC 所有特性都可归结为一句话:它划定了一条布局边界,让内部规则不外溢、外部影响不侵入。当你遇到「margin 莫名合并」「父元素高度为 0」「元素被浮动盖住」这类问题时,第一反应就该想到——给它开一个 BFC。