跳到主要内容

BFC 与 IFC:格式化上下文

面试速答(30 秒版 TL;DR)

  • 格式化上下文(Formatting Context) 可以理解为浏览器的一块排版规则区域,里面的盒子如何排列、如何互相影响,都由这套规则决定。
  • BFC(Block Formatting Context) 主要管块级布局;高频考点是:包含浮动、阻止外边距合并、避免和浮动重叠
  • IFC(Inline Formatting Context) 主要管行内内容排版;高频考点是:行盒(line box)、空白字符、基线对齐、vertical-align
  • 面试实战里,BFC 常用于解释“为什么父元素高度塌陷”“为什么 margin 合并”“为什么旁边内容绕开浮动”;IFC 常用于解释“为什么行内元素有缝隙”“为什么图片底部有空白”。

心智模型

你可以把格式化上下文理解成“排版结界”:

  • 进入 BFC,就按块级盒子的规则排
  • 进入 IFC,就按行内内容的规则排

很多看似诡异的 CSS 现象,本质上不是“浏览器出 bug”,而是你没搞清楚元素当前处在哪种格式化上下文里。


一、什么是 BFC

BFC 是块级格式化上下文,可以理解成一个相对独立的块级布局区域。

它最值得记住的 3 个效果是:

  1. 会包含内部浮动元素
  2. 能阻止和外部浮动重叠
  3. 能隔离同一上下文里的外边距合并问题

常见触发方式

触发方式示例备注
根元素html天生存在
浮动元素float: left有副作用
绝对/固定定位position: absolute/fixed元素脱流
overflowvisibleoverflow: hidden可能裁剪内容
display: inline-block容器行为改变
display: flow-root最推荐,语义最明确
工程建议

现在最推荐用 display: flow-root 创建 BFC,因为它的意图最明确,不需要顺带引入 overflow 裁剪之类的副作用。


二、BFC 的高频应用

1)清除浮动

父元素里全是浮动子元素时,父元素高度可能塌陷。让父元素形成 BFC 后,浮动子元素会重新参与它的高度计算。

.parent {
display: flow-root;
}

2)阻止外边距合并

两个块级元素在同一个 BFC 里,垂直方向的 margin 可能发生折叠。把其中一个元素包进新的 BFC,可以把它们隔开。

3)实现两栏自适应

左侧浮动定宽,右侧内容创建 BFC 后,不会和浮动区域重叠,因此能形成“左固定、右自适应”的经典布局。


三、什么是 IFC

IFC 是行内格式化上下文,行内元素、文本节点等会在一行一行的**行盒(line box)**中排布。

它的高频特征是:

  1. 行内内容会从左到右依次排
  2. 空间不够时会自动换到下一行
  3. 同一行里的对齐默认受**基线(baseline)**影响

例如下面这些都属于 IFC 关注的问题:

  • 文本为什么会换行
  • inline-block 元素之间为什么会出现空白
  • 图片为什么底部总像多出一条缝
  • vertical-align: middle 到底在和谁对齐

四、IFC 的高频应用

1)解释图片底部空白

img 默认按行内元素参与 IFC,对齐基线时会给字母下行区预留空间,所以底部常会看到一条缝。

常见解法:

img {
display: block;
}

或者:

img {
vertical-align: middle;
}

2)解释 inline-block 之间的间隙

inline-block 本身按行内级盒子参与 IFC,HTML 源码里的换行和空格会被当成文本空白渲染出来。

常见解法:

  • 去掉标签之间的空白字符
  • 给父元素设 font-size: 0
  • 改用 flex / grid / gap

3)解释 vertical-align

vertical-align 不是“相对父元素垂直居中”,而是同一行盒内行内级盒子之间的垂直对齐规则


五、典型题 & 标准答法

Q1:什么是 BFC?有什么作用?

答法:

  • BFC 是独立的块级格式化上下文。
  • 高频作用有 3 个:包含浮动、阻止外边距合并、避免与浮动重叠。
  • 现代最推荐的触发方式是 display: flow-root

Q2:为什么给元素加了 overflow: hidden 能“清除浮动”?

答法:

  • 因为 overflow 不为 visible 时会形成新的 BFC。
  • BFC 计算高度时会把内部浮动子元素算进去,所以父元素不再塌陷。
  • 但它的副作用是可能裁剪超出边界的内容,所以不如 flow-root 语义清晰。

Q3:为什么 img 底下会有缝?

答法:

  • 因为图片默认按行内元素参与 IFC,和文本基线对齐。
  • 浏览器会为下行区预留空间,所以视觉上像底部多出空白。

常见追问

1)Flex 和 Grid 还算 BFC 吗?

更准确的说法是:

  • 它们会创建自己的格式化上下文,内部子项分别参与 FFC 和 GFC
  • 面试里可以补一句:它们也具备“独立布局区域”的隔离效果,但不要把概念粗暴等同

2)所有 margin 合并都能用 BFC 解释吗?

大部分面试场景可以这么答,但要注意:

  • margin 折叠主要发生在同一 BFC 内的块级盒子之间
  • 横向 margin 不会折叠

3)为什么 BFC 常和浮动一起出现?

因为 BFC 正好能解释 float 时代最常见的三个问题:高度塌陷、文字环绕、两栏布局。


易错点/坑

  • 把 BFC 记成“一个属性”,其实它是布局上下文,不是单独的 CSS 属性。
  • 只背触发条件,不知道它到底解决什么问题。
  • vertical-align 误解成任意元素都能相对父元素垂直居中。
  • 忽略行内空白字符对 inline-block 布局的影响。

速记要点(可背诵)

  • BFC 记 3 句:包含浮动、阻止 margin 合并、避免和浮动重叠。
  • IFC 记 3 词:行盒、基线、空白字符。
  • flow-root 是现代创建 BFC 的推荐写法。