> ## Documentation Index
> Fetch the complete documentation index at: https://opc-43d279b8.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# BFC (块格式化上下文)

> BFC 的触发条件、清除浮动与 margin 折叠，以及它与 FFC/GFC 的边界。

> 我对 BFC 的理解是分几次补的：先用它清浮动，后来才弄懂 margin 合并，最后是隔离。

***

## Q1: BFC 究竟是什么？为什么要有它？

**1. 混沌的普通流世界**

在 CSS 默认的普通流（Normal Flow）中，块级元素就像一个个没有边界的军阀。它们的外边距（margin）会互相穿透合并，如果里面有浮动（float）的士兵飞天脱离了地面，军阀首领（父容器）就根本无法感知到士兵的存在，导致自身高度塌陷为 0。

**2. 致命痛点：高度塌陷与 margin 重叠**

两个相邻 div 的上下 margin 会合并成一个（取较大值），导致间距异常；浮动元素脱离文档流后父容器高度变成 0，后续排版全部崩溃重叠。在真实项目中，这两大问题曾是前端开发者最头疼的排版噩梦。

**3. 降维隔离结界: BFC 的诞生**

BFC 的全称是 **Block Formatting Context（块级格式化上下文）**。你可以把它理解为张鑫旭在《BFC 详解》中定义的\*\*"结界'\*\*。一旦某个元素通过特定属性触发了 BFC，它就会在引擎内部化身为一个物理隔离的堡垒。

**4. 触发条件与引擎判定**

在 Blink 的 `BlockLayoutAlgorithm` 中，`CreatesNewFormattingContext` 是一个布尔值判定函数--只要元素的 `float` 不为 `none`、`position` 为 `absolute/fixed`、`display` 为 `inline-block/flow-root`、或 `overflow` 不为 `visible`，BFC 结界瞬间开启。注意 `display: flex/grid` 建立的是 FFC/GFC 而不是 BFC，但同样能隔离子元素的外边距。其中 `display: flow-root` 是最纯净无副作用的 BFC 触发器，它就是为创建 BFC 而生的。

**5. 关键洞察：从 hack 到标准的工程演进**

在 `flow-root` 标准诞生前，开发者只能用 Nicolas Gallagher 发明的 `clearfix` 微黑客写法或有副作用的 `overflow: hidden` 来清除浮动。现代方案中，新业务全面采用 Flex 或 Grid 布局体系，它们底层建立的 FFC/GFC 同样自带绝对隔离属性，让浮动清除和 margin 重叠这类上古问题彻底从历史舞台消失。

**BFC 解决的核心问题：**

```text theme={null}
问题：普通流中 margin 互相穿透、浮动元素导致父容器高度塌陷

父容器内只有一个 float: left 的图片 → 父容器高度 = 0px → 后续排版全部崩溃重叠
相邻 div 的上下 margin: 30px 与 margin: 50px → 实际间距 = 50px（合并取大），而非 80px

解决：触发 BFC 结界，建立物理隔离的沙箱

给父容器加 overflow: hidden（触发 BFC）→ 引擎强制将浮动元素高度纳入计算 → 高度恢复正常
BFC 内部的 margin 不会与外部合并 → 间距符合预期
```

> [!NOTE]
>
> BFC 是浏览器布局引擎在普通流中强行划定的一个物理隔离的沙箱结界，内部的浮动和 margin 动荡绝不能渗透出去污染外部。

> [card] 🚫 没有 BFC
>
> 父容器内如果只有一个 `float: left` 的图片。由于浮动元素脱离文档流，父容器在物理引擎中计算时认为里面空无一物，高度直接变成 0px，导致后续排版全部崩溃重叠。就像一个军阀的士兵全飞到天上去了，首领以为自己一个兵都没有，直接"阵亡'。

> [card] ✅ 引入 BFC
>
> 给父容器加上 `overflow: hidden`（触发 BFC 结界）。渲染引擎瞬间切换计算模式，强制把浮动图片的高度纳入父容器计算，父级高度瞬间被撑开恢复正常。就像给军阀的领地建了一圈城墙，所有士兵无论飞到哪里，城墙都能把他们"兜住'。

> [!TIP]
>
> BFC 就像给元素施了一个"结界"（引用自张鑫旭）。普通流中的元素就像没有边界的开放区域——隔壁的"margin 噪音"直接传过来（margin 重叠），飘在天上的"浮动士兵"让首领以为自己一个兵都没有（高度塌陷）。一旦触发 BFC，就像张鑫旭在《BFC 详解》中说的那样：结界内部的任何布局动荡（浮动、外边距合并）都不能渗透出去污染外部，外部的元素也休想越界覆盖其本身的领土。`display: flow-root` 就是最纯净的开结界方式——不裁剪内容，零副作用，它就是为创建 BFC 而生的。

> [!TIP]
>
> 回答时先说"为什么'（高度塌陷与 margin 重叠两大痛点），再说"怎么解决"（BFC 隔离结界机制）。重点是理解问题的本质，而不是背定义。

***

## Q2: 如何触发 BFC 结界？

BFC 的是一个**布尔值开关判定机制**，关键逻辑是 1 步：

```text theme={null}
┌───────────────────────────────────────┐
│        ComputedStyle（计算样式）        │  ← 浏览器渲染引擎读取元素最终样式
└─────────────────┬─────────────────────┘
                  │ 命中以下任意一条规则？
                  ▼
┌───────────────────────────────────────┐
│        BFC 结界开启                     │  ← 布局算法切换为隔离模式
└───────────────────────────────────────┘
```

只要元素的 `ComputedStyle` 命中了以下任何一条规则，BFC 结界瞬间开启：

1. **浮动**：`float` 属性不为 `none`。
2. **绝对定位**：`position` 为 `absolute` 或 `fixed`。
3. **改变了 display 机制**：`display` 为 `inline-block`、`table-cell`、`flex`、`grid`、`flow-root`。
4. **截断溢出**：`overflow` 不为 `visible`（如 `hidden`、`auto`、`scroll`）。

> [!WARNING]
>
> 正如 W3C CSS 规范在 [CSS Display Module Level 3](https://www.w3.org/TR/css-display-3/) 中定义的：**"A block formatting context is a part of a visual CSS layout for block-level boxes.'** 以下条件均可触发新的格式化上下文：
>
> * `display: flow-root` 是**最纯净、无副作用**的 BFC 触发器，它就是为创建 BFC 而生的。
> * `overflow: hidden` 虽然常用，但会导致内容裁剪（弹窗、下拉菜单无法溢出显示），是工业级代码中最常见的"屎山"来源。
> * 注意区分：`display: flex` 触发的是 **FFC（Flex Formatting Context）**，`display: grid` 触发的是 **GFC（Grid Formatting Context）**，它们的隔离特性与 BFC 等价，但属于更高维度的布局上下文。

> [!TIP]
>
> 普通流就像一个没有边界的开放区域（引用自张鑫旭的"结界"比喻）。触发 BFC 的条件就像打开结界的"咒语"——`float` 不为 `none`、`position: absolute`、`overflow: hidden`、`display: flex/grid/flow-root`，任何一个都能瞬间开启结界。一旦结界开启，内部的浮动和 margin 动荡绝不能渗透出去，外部也休想越界。张鑫旭指出，其中 `display: flow-root` 是最纯净的"开结界咒语"——不裁剪内容、不影响定位、不改变尺寸计算规则，唯一的效果就是创建一个独立的格式化上下文。

***

## Q3: BFC 与 FFC、GFC 有什么区别？

### 基础梳理

| 对比维度 | BFC（块级格式化上下文） | FFC（弹性格式化上下文） | GFC（网格格式化上下文） |
| - | - | - | - |
| **触发方式** | `overflow: hidden`、`float`、`position: absolute` 等 | `display: flex` | `display: grid` |
| **布局模型** | 块级盒子垂直排列 | 弹性盒子一维排列（行或列） | 网格盒子二维排列（行+列） |
| **清除浮动** | 是 | 是（浮动被忽略） | 是（浮动被忽略） |
| **阻止 margin 重叠** | 是 | 是 | 是 |
| **子元素 float 生效** | 生效 | **无效**（被引擎物理忽略） | **无效**（被引擎忽略） |

### 专家视角深度剖析

很多人只能背下上面的表格，但实际更在意的是：**为什么 Flex/GFC 中 float 会被"物理无效化"？这是 W3C 的设计失误还是刻意为之？**

这是 W3C 规范的**刻意突破**。W3C 在 [CSS Flexible Box Layout Module Level 1](https://www.w3.org/TR/css-flexbox-1/) 中严苛地写明：一旦一个元素成为了 Flex Container，它的直接子元素就会瞬间发生"阶级跃迁"，成为 Flex Items。在这个强大的 FFC 上下文中，所有作用于子元素上的浮动魔法（`float`、`clear`）会被浏览器的 C++ 引擎**完全忽略、物理无效化**；`vertical-align` 同样会被忽略——它本身是用于行内元素垂直对齐的属性，在 flex item 上不生效。它甚至连个错误都不会报，就仿佛那个 `float` 属性压根不存在一样。

这样设计的底层原因是为了**保证弹性布局系统的纯净性**。如果允许 float 在 Flex 容器内生效，就意味着同一套排版算法需要同时处理"流式浮动"和"弹性对齐"两种互相矛盾的模型，复杂度会指数级爆炸，性能和可预测性都会崩溃。

```css theme={null}
/* Flex 容器中 float 完全无效 */
.flex-container {
  display: flex;
}
.flex-container .item {
  float: left; /* 被浏览器物理忽略，不会产生任何浮动效果 */
}
/* 关键点：高维度上下文对低维规则的突破，保证布局系统的纯净性 */
```

***

## Q4: 经典面试题：margin 重叠的三种场景

margin 重叠（margin collapsing）是 BFC 相关的高频踩坑题。它只发生在**普通流**中的**垂直方向**上。

**相邻兄弟元素的 margin 重叠：**
两个相邻的块级兄弟，上一个的 `margin-bottom` 和下一个的 `margin-top` 会合并为两者中的较大值。

**父子元素的 margin 重叠：**
父容器没有 `border`、`padding`、`inline-content` 且没有触发 BFC 时，子元素的 `margin-top` 会"穿透"到父容器外部，表现为父容器的 margin-top。

**空块元素的自身 margin 重叠：**
一个没有 `border`、`padding`、`height`、`min-height` 的空块元素，自身的 `margin-top` 和 `margin-bottom` 会合并。

**关键区别：**

| 场景 | margin 重叠？ | 触发 BFC 后 |
| - | - | - |
| 相邻兄弟 div | 合并为较大值 | 各自独立（BFC 隔离） |
| 父子元素（无 border/padding） | 子 margin 穿透到父外 | 子 margin 被限制在父内 |
| 空块元素 | 上下 margin 合并 | 不适用（元素本身无子内容） |

> [!TIP]
>
> 在现代布局中，优先使用 Flex 或 Grid 布局替代普通流，可从根源上消灭 margin 重叠问题。若必须使用普通流，对需要隔离 margin 的容器添加 `display: flow-root` 触发 BFC，避免使用有副作用的 `overflow: hidden`。

***

## 🔍 源码：Blink 引擎是如何实现的？

Blink 引擎中 BFC 的判定和高度计算是怎么实现的？

在 Chrome 的 Blink 渲染引擎源码中，是否创建 BFC 是一个布尔值判定（详见 [Blink 源码 src/core/layout/block\_layout\_algorithm.cc](https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/core/layout/block_layout_algorithm.cc)）。BFC 对应的布局对象是 `LayoutBlockFlow`，它自己维护一份浮动元素列表（`floating_objects_`）：

```cpp theme={null}
// 详见：Blink 源码 src/core/layout/block_layout_algorithm.cc
// 判定当前样式是否需要开启新的格式化上下文（伪代码，保留判定条件）

bool CreatesNewFormattingContext(const ComputedStyle& style) {
  return style.IsFloating() ||
         style.HasOutOfFlowPosition() ||          // absolute / fixed
         style.IsDisplayInlineBlock() ||
         style.IsDisplayFlowRoot() ||             // 纯净的 BFC 触发器
         style.IsDisplayTable() ||
         style.IsDisplayFlex() ||
         style.IsDisplayGrid() ||
         style.Overflow() != EOverflow::kVisible;
}

// 高度计算阶段：BFC 在计算自身逻辑高度时，
// 会把 floating_objects_ 中浮动盒的边界一并纳入，
// 这就是父容器能包住浮动子元素、不再高度塌陷的原因。
```

`display: flow-root` 在 Blink 中是怎么判定的？

`display: flow-root` 在 Blink 中通过 [`IsDisplayFlowRoot()`](https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/core/style/computed_style.h) 方法判定，该方法直接检查 `display` 属性的枚举值是否为 `EDisplay::kFlowRoot`。它是最为"纯净"的 BFC 触发器--没有任何视觉副作用，不裁剪内容、不影响定位、不改变尺寸计算规则，唯一的效果就是创建一个新的块级格式化上下文。

```cpp theme={null}
// ComputedStyle 中的判定方法
inline bool IsDisplayFlowRoot() const {
  return Display() == EDisplay::kFlowRoot;
}
```

***

## 十、及格回答 vs 满分回答

### 问题："什么是 BFC？怎么触发？它主要解决什么业务问题？"

**及格回答（60-70分）：**

> "BFC 就是块级格式化上下文。触发条件有 float、position absolute、overflow hidden 还有 display flex 之类的。主要用来解决父元素里面有浮动元素导致高度塌陷的问题，还有解决上下两个相邻 div 的 margin 塌陷重叠问题。"

问题出在：**知道规则但不理解设计**。

**满分回答（90-100分）：**

> BFC 的本质是浏览器布局引擎在普通流（Normal Flow）中强行划定的一个**物理隔离的沙箱结界**。它的核心法则是：结界内部的任何布局动荡（如浮动、外边距合并）都不能渗透出去污染外部；外部的元素也休想越界覆盖其本身的领土。BFC 解决了两大历史痛点：浮动元素导致父容器高度塌陷、相邻元素的垂直 margin 互相穿透合并。张鑫旭在《BFC 详解》中将其比喻为"结界"——一旦触发，内部的浮动和 margin 动荡绝不能渗透出去污染外部，这一形象化的定义成为中文社区理解 BFC 的经典起点。<sup>\[1]</sup>

> 在 Blink 的 `BlockLayoutAlgorithm` 中，一旦通过 `CreatesNewFormattingContext` 判定确认元素创建了新上下文，引擎在计算该块级高度时，就会执行 `IncludeFloatingObjectsHeight()`——强行将内部浮动盒子边界并入自身的逻辑高度计算中，从而从物理引擎级别瞬间抹除"高度塌陷"的灾难。触发条件包括 `float` 不为 `none`、`position` 为 `absolute/fixed`、`display` 为 `inline-block/flow-root/flex/grid`、`overflow` 不为 `visible`。<sup>\[2]</sup>

> 在真实的工业老项目中，最大的屎山代码往往来自于滥用 `overflow: hidden` 来触发 BFC 清除浮动，这极易导致复杂的弹窗和下拉菜单遭遇**无情裁剪**。在 `flow-root` 标准诞生前的至暗时刻，Nicolas Gallagher 发明了"微 clearfix"黑客写法（`::after` + `clear: both` + `display: table`），成为工业界清除浮动的事实标准。张鑫旭在《CSS Display 之 flow-root 详解》中指出，`display: flow-root` 是最纯净无副作用的 BFC 触发器，它就是为创建 BFC 而生的。在现代架构中，对于新业务，我们则会全面采用 Flex 或 Grid 布局体系，它们在底层建立的 FFC/GFC 同样自带绝对隔离属性，让浮动清除和 margin 重叠这类上古问题彻底从历史舞台消失。<sup>\[3]</sup>

### 常见追问

> [accordion] 第一层: overflow: hidden 会导致菜单裁剪, 有没有不裁剪的经典 Hack?
>
> **答题要点：**
> 不能只答 `overflow: hidden`，必须提到 `clearfix` 和 `flow-root` 两种替代方案。
>
> **高分回答：**
> "在 `flow-root` 标准诞生前的至暗时刻，前端圈推崇 Nicolas Gallagher 发明的 `clearfix` 微黑客写法。原理是不在父元素身上动刀子，而是利用 `::after` 伪元素在父容器的最后强行生成一个无形的隐式内联元素，并对其设置 `clear: both;` 以及 `display: table;`。这并不是让父元素变成 BFC，而是利用了 `clear` 属性的底层物理强制力：强行迫使这最后一块隐形的砖头必须被放置在所有浮动元素的正下方！父容器为了包裹住这块砖头，自然就顺带着把上面那些浮动的元素全都包裹进去了。现代方案则直接使用 `display: flow-root`，一行代码零副作用。"

> [accordion] 第二层: Flex 容器中的子元素设置 float: left 会发生什么?
>
> **答题要点：**
> 结合 W3C 规范解释"突破"机制。
>
> **高分回答：**
> "W3C 规范严格地写明：一旦一个元素成为了 Flex Container，它的直接子元素就会瞬间发生'阶级跃迁'，成为 Flex Items。在这个强大的 FFC 上下文中，所有作用于子元素上的浮动魔法（`float`、`clear`）会被浏览器的 C++ 引擎**完全忽略、物理无效化**；`vertical-align` 同样在 flex item 上被忽略（它本身是用于行内元素垂直对齐的属性）。它甚至连个错误都不会报，就仿佛那个 `float` 属性压根不存在一样。这就保证了现代弹性布局系统不会受到上古流体规则的污染。"

> [accordion] 第三层: BFC 会阻止所有 margin 重叠吗?只阻止相邻兄弟的吗?
>
> **答题要点：**
> 必须分场景讨论！BFC 阻止的是 BFC 边界两侧的 margin 重叠，而非"内部所有"。
>
> **高分回答：**
> "分三种情况：
> **1. 相邻兄弟元素**：如果两个兄弟各自处于不同的 BFC 中（如其中一个被 BFC 容器包裹），它们的 margin 不会重叠。
> **2. 父子元素**：给父容器触发 BFC 后，子元素的 margin 会被'锁'在父容器内部，不会再穿透到外部。
> **3. BFC 内部的子元素之间**：如果 BFC 内部有多个子元素，它们之间的 margin **仍然会正常重叠**！BFC 只阻止的是'跨结界'的 margin 穿透，结界内部的普通流规则依然有效。"

> [accordion] 第四层: display: flow-root 在哪些场景下是最佳选择?
>
> **答题要点：**
> 结合实际工程场景解释 flow-root 的适用范围。
>
> **高分回答：**
> "`display: flow-root` 是最纯净的 BFC 触发器，没有任何视觉副作用。最佳使用场景：
> **1. 清除浮动**：替代 `overflow: hidden`，不会裁剪内容（如下拉菜单、弹窗）。
> **2. 隔离 margin**：阻止子元素的 margin 穿透到父容器外部。
> **3. 包含浮动子元素**：让父容器的高度包含浮动的子元素。
> **兼容性**：Chrome 58+、Firefox 53+、Safari 11+、Edge 79+。对于需要支持 IE 的项目，仍需使用 `clearfix` hack。"

> [accordion] 第五层: 在 Grid 布局中, BFC 的行为有什么变化?
>
> **答题要点：**
> 必须分场景讨论！Grid 容器自带隔离属性。
>
> **高分回答：**
> "Grid 容器（`display: grid`）会创建一个新的格式化上下文（GFC），它具有与 BFC 相同的隔离特性：
> **1. 浮动无效**：Grid 子元素上的 `float` 属性会被忽略。
> **2. margin 隔离**：Grid 子元素的 margin 不会穿透到 Grid 容器外部。
> **3. 高度包含**：Grid 容器的高度会包含所有子元素。
> 所以在 Grid 布局中，你不需要额外触发 BFC 来解决浮动和 margin 问题。但如果 Grid 容器内部有嵌套的普通流元素，BFC 规则仍然适用。"

> [accordion] 🔥 杀手锏追问: 为什么 margin 重叠只发生在垂直方向, 水平方向为什么不重叠?
>
> **答题要点：**
> 对比垂直与水平的布局语义，点出 W3C 的设计哲学。
>
> **高分回答：**
> "这是因为 W3C 在设计 CSS 时借鉴了传统排版的语义--**垂直方向是'流式排版'，水平方向是'容器约束'**。
> 在垂直方向上，块级元素是从上到下依次排列的，相邻元素之间的 margin 合并是为了'连续文本段落'的排版美观--想象一篇文章中每段的 `margin-bottom: 10px` 和下一段的 `margin-top: 10px`，合并后间距是 10px 而不是 20px，这符合传统出版物的排版审美。
> 而在水平方向上，块级元素的宽度是由容器约束的（`width: 100%`），两个兄弟块级元素根本不会出现在同一行上，所以水平 margin 没有'相邻'的概念，自然无法重叠。只有在 `display: inline` 或 `display: inline-block` 的行内元素上，水平 margin 才会生效，但行内元素有自己独立的排版规则，不参与块级 margin 重叠。"

> [accordion] 🔥 杀手锏追问: BFC 在移动端滚动穿透问题中有什么应用?
>
> **答题要点：**
> 结合移动端实际场景解释 BFC 的工程应用。
>
> **高分回答：**
> "移动端的滚动穿透问题（Scroll Chaining）是指：当弹窗（Modal）打开时，背景页面仍然可以滚动。BFC 在这个问题中的应用有限，但可以辅助解决：
> **1. 弹窗容器触发 BFC**：给弹窗容器设置 `overflow: auto` 或 `overflow: hidden`，创建独立的滚动上下文。
> **2. 配合 overscroll-behavior**：使用 CSS 属性 `overscroll-behavior: contain` 阻止滚动传播到父容器。
> **3. 弹窗内容超出时**：如果弹窗内容超出视口，BFC 容器会创建独立的滚动区域，不会影响背景页面。
> 但 BFC 本身不能完全解决滚动穿透，还需要配合 `position: fixed` 或 `touch-action` 等属性。"

> [accordion] 🔥 杀手锏追问: BFC 和 Flex/Grid 布局在性能上有什么区别?
>
> **答题要点：**
> 对比不同布局方式的性能差异。
>
> **高分回答：**
> "BFC 和 Flex/Grid 布局在性能上有显著差异：
> **1. BFC**：只是创建一个隔离的格式化上下文，不改变布局算法。性能开销很小，主要是阻止 margin 穿透和包含浮动。
> **2. Flex 布局**：使用一维布局算法，需要计算主轴和交叉轴的空间分配。性能开销中等，适合简单的线性布局。
> **3. Grid 布局**：使用二维布局算法，需要同时计算行和列。性能开销较大，适合复杂的网格布局。
> **4. 性能对比**：在相同元素数量下，BFC 的性能最好，Flex 次之，Grid 最差。但在复杂布局中，Grid 可以减少 DOM 嵌套层级，反而可能提升整体性能。
> **最佳实践**：根据布局复杂度选择合适的方案。简单的隔离用 BFC，线性布局用 Flex，复杂网格用 Grid。"

***

## 📚 延伸阅读与引用参考

* 🔗 [CSS Display Module Level 3 - W3C 规范](https://www.w3.org/TR/css-display-3/)：W3C 官方对块级格式化上下文（BFC）的权威定义，阐述了格式化上下文的创建条件与布局规则。<sup>\[1]</sup>
* 📖 [Blink 源码 block\_layout\_algorithm.cc](https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/core/layout/block_layout_algorithm.cc)：Chrome Blink 引擎中 BFC 判定与高度计算的实现，`CreatesNewFormattingContext` 函数是所有触发条件的终极开关。<sup>\[2]</sup>
* 🟢 [张鑫旭 - BFC 详解](https://www.zhangxinxu.com/wordpress/2012/08/bfc-block-formatting-context/)：国内 CSS 第一人张鑫旭对 BFC "结界"概念的经典通俗解释，从"什么是 BFC"到"如何触发"再到"解决什么问题"的完整梳理，是中文社区理解 BFC 的起点之作。<sup>\[3]</sup>
* 🧑‍💻 [张鑫旭 - CSS Display 之 flow-root 详解](https://www.zhangxinxu.com/wordpress/2016/11/css-display-flow-root/)：张鑫旭对 `display: flow-root` 这一最纯净 BFC 触发器的深度剖析，对比了 `overflow: hidden` 的副作用与 `flow-root` 的零副作用优势。
* 📘 [Nicolas Gallagher - A New Micro Clearfix Hack](https://nicolasgallagher.com/micro-clearfix-hack/)：Nicolas Gallagher 发明的"微 clearfix"黑客写法的原始出处，使用 `::after` 伪元素 + `clear: both` + `display: table` 的组合方案，是 `flow-root` 标准诞生前工业界清除浮动的事实标准。
* 🔍 [Lea Verou - CSS Secrets (O'Reilly)](https://www.oreilly.com/library/view/css-secrets/9781449372675/)：W3C 专家 Lea Verou 的《CSS 揭秘》，从"为什么需要 BFC"的底层设计哲学出发，帮助开发者理解格式化上下文的工程演进逻辑。
* 🎨 [Josh W. Comeau - An Interactive Guide to Flexbox](https://www.joshwcomeau.com/css/a-interactive-guide-to-flexbox/)：Josh Comeau 的交互式 Flexbox 指南，帮助理解为什么 Flex 容器（FFC）会天然自带 BFC 级别的隔离属性，float 在 Flex 内部为何被"物理无效化"。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.