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 个效果是:
- 会包含内部浮动元素
- 能阻止和外部浮动重叠
- 能隔离同一上下文里的外边距合并问题
常见触发方式
| 触发方式 | 示例 | 备注 |
|---|---|---|
| 根元素 | html | 天生存在 |
| 浮动元素 | float: left | 有副作用 |
| 绝对/固定定位 | position: absolute/fixed | 元素脱流 |
overflow 非 visible | overflow: 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)**中排布。
它的高频特征是:
- 行内内容会从左到右依次排
- 空间不够时会自动换到下一行
- 同一行里的对齐默认受**基线(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 的推荐写法。