05BFC 块级格式化上下文
BFC(Block Formatting Context,块级格式化上下文)是 CSS 里最著名的「看不见的概念」。 其实它一点也不玄:一块自成一体的独立布局区域—— 浮动章的高度塌陷、盒模型章的 margin 合并,答案都是它。学会触发 BFC,等于拿到一把修复布局的万能钥匙。
一、BFC 是什么:一块「独立自治区」
BFC 全称 Block Formatting Context(块级格式化上下文)。 它不是某个属性,而是一种渲染状态:满足特定条件的元素,会圈出一块 「独立自治区」——区内的布局影响不到区外,区外的规则也进不了区内。
最贴切的比喻是防水袋:把东西装进袋子封好口, 袋子里就算泡着水(浮动、margin),也漏不到外面;外面的浪(相邻元素)同样打不湿袋子里的内容。 一个元素一旦形成 BFC,它就变成一个封好口的防水袋。
display: flow-root),
塌陷、合并、重叠这些毛病立刻消失,就说明 BFC 成立了。二、触发方式速查表:怎么造一个 BFC
让一个元素成为 BFC 的方法很多,但绝大多数是「顺带的副作用」——
真正为造 BFC 而生的只有 display: flow-root。
| 触发方式 | 副作用 | 推荐度 |
|---|---|---|
| display: flow-root | 无!专为造 BFC 而生的现代专用值 | ★★★★★ 首选 |
| overflow: hidden / auto / scroll | 溢出内容被裁切,auto / scroll 可能出现滚动条 | ★★★ 确定无溢出时可用 |
| display: inline-block | 变成行内块:宽度收缩、换行有缝隙 | ★★ |
| float: left / right | 自己先浮动起来,布局跟着连锁变化 | ★ 基本只见于老代码 |
| position: absolute / fixed | 脱离文档流,要重新操心定位 | ★ 别为 BFC 用它 |
| display: flex / grid(容器) | 布局模式整个改变 | 顺带的:flex/grid 容器天然是 BFC |
| contain: content / layout | 语义是渲染性能隔离 | 了解即可 |
flow-root。
其余方式要么裁内容、要么改布局,都是「为了治感冒把胳膊截了」——
除非老项目兼容性要求,否则一律 display: flow-root。三、应用一:清除浮动,治好高度塌陷
浮动章埋过一颗雷:子元素全部浮动后脱离文档流, 父元素当它不存在,高度塌成 0,边框只剩一条线,后面的元素直接顶上来——这就是「高度塌陷」。 BFC 的第一条铁律正是解药:BFC 计算高度时,会把内部的浮动子元素也包进去。
.parent 里 display: flow-root 那行注释打开(删掉 /* */),父级立刻把孩子「捞」回来clear: both,或者用 .clearfix::after 伪元素大法——
殊途同归,都是想办法让父级承认浮动孩子的高度。
现在一句 display: flow-root 就够了。四、应用二:阻止 margin 合并
盒模型章讲过「父子 margin 穿透」: 父元素没有 padding / border 挡着时,第一个孩子的 margin-top 会合并到父级身上, 看起来像「孩子把父级整个顶跑了」。BFC 的第二条铁律: BFC 区域内外的 margin 互不合并——袋子一封口,margin 就漏不出去了。
.parent 里 overflow: hidden 的注释打开,间距立刻回到父级「肚子」里五、应用三:两栏自适应,文字不再环绕
「左图右文」的经典布局:图片浮动后,文字默认会环绕它排, 流过长长的文字会绕到图片下面去——做图文混排是特性,做两栏布局就是灾难。 BFC 的第三条特性:BFC 区域不会与外部浮动元素重叠。 给文字块触发 BFC,它就乖乖缩成右边一栏,和图片平起平坐。
.text 里 overflow: hidden 的注释打开,文字块立刻变成规整的右栏——再删掉对比环绕效果display: flex 更直观——
下一章 Flex 就讲,这里先记住 BFC 这条老路。六、flow-root vs overflow:hidden 的取舍
既然 overflow: hidden 也能触发 BFC,为什么还要推荐
display: flow-root?因为 overflow 的本职是溢出处理:
它会把探出盒子的内容裁掉——下拉菜单、气泡角标、
悬浮提示,探出去的部分统统被「切头」。
.a 的 overflow: hidden 改成 display: flow-root,徽章立刻恢复| 对比项 | overflow: hidden | display: flow-root |
|---|---|---|
| 溢出内容(下拉菜单、角标) | 被裁切,探出去就消失 | 原样显示 |
| 滚动条 | auto / scroll 值可能冒出滚动条 | 永不出现 |
| 语义 | 顺手借来的副作用,读代码要想一层 | 明明白白:我就是来造 BFC 的 |
| 兼容性 | 全浏览器通吃 | 现代浏览器全支持(仅 IE 不认识) |
| 推荐场景 | 老项目维护、确定无溢出 | 现代项目清除浮动 / 防合并的首选 |
overflow: hidden,
后来产品要在卡片右上角加个「NEW」角标,探出去的部分死活不显示——
查了半天才发现是被 overflow 裁了。除非你就是想裁切,否则别用 overflow 当清浮动的工具。七、本章小结
- BFC(Block Formatting Context,块级格式化上下文)是一块独立布局区域:区内布局不影响区外,区外也影响不到区内——「防水袋」。
- BFC 三条铁律:计算高度包含浮动子元素;区域内外 margin 不合并;区域不与外部浮动重叠。
- 触发方式首选
display: flow-root——无副作用的专用值;overflow: hidden会裁切溢出内容,只在老代码里将就用。 - 三大应用:① 清浮动治高度塌陷;② 阻止父子 / 相邻 margin 合并;③ 做左图右文两栏自适应。
- flex / grid 容器天然是 BFC——所以弹性盒布局里从来不会塌陷,这也是现代布局省心的一部分。
- 面试加分项:能说清「BFC 不是属性而是渲染状态」,以及 flow-root 与 overflow 的取舍。
overflow: auto 修,
观察会不会冒出滚动条;② 给第四节的孩子再加一个 margin-bottom: 30px,
父级触发 BFC 前后分别看底部间距的变化;③ 用「左浮图 + 右侧 BFC 文字块」做一张新闻卡片,
再把图片 float 改成 right,确认文字栏自动换到左边。