第六章 · 6.5 节
浮动与 BFC
在 Flexbox 与 Grid 出现之前,float 曾是唯一能实现"多栏并排"的手段,也因此留下了一整套配套的 hack 技巧。今天我们很少再用 float 搭建整体布局,但它引出的 BFC(块级格式化上下文)概念,至今仍是排查布局异常的重要工具。
float 的原始用途
float 最初是为"文字环绕图片"设计的:设置了 float 的元素会脱离正常文档流,向左或向右靠拢,后面的行内内容则环绕在它周围。
img.thumb { float: left; margin-right: 12px; }
效果预览:文字环绕
图
这是一段环绕在浮动图片右侧的文字,行文会自动避开浮动元素占据的区域,直到超出浮动元素的高度后才会恢复满宽排列,这正是 float 最初被设计用来解决的排版问题。
高度塌陷问题
float 元素脱离了文档流,一个尴尬的后果是:如果父元素只包含浮动的子元素,父元素会"看不到"它们的高度,表现为高度塌陷为 0。
/* 父元素高度会塌陷 */ .row { border: 1px solid #c9cabf; } .row .col { float: left; width: 50%; }
经典的补救写法是 clearfix,本质是用一个伪元素强制"清除浮动":
.clearfix::after { content: ""; display: table; clear: both; }
什么是 BFC
BFC(Block Formatting Context,块级格式化上下文)是页面中一块"独立的渲染区域"——BFC 内部的盒子如何布局,不会影响到外部;反过来,外部元素也无法影响 BFC 内部的布局。它可以理解为一个隔离的排版容器。
clearfix 之所以有效,本质是给父元素触发了 BFC——BFC 会包裹住内部所有浮动元素的高度,不再塌陷。这也是为什么现代写法更推荐直接触发 BFC,而不是额外插入清除用的伪元素。
如何创建 BFC
| 触发方式 | 说明 |
|---|---|
| overflow: hidden / auto | 最常见的写法,但会连带裁剪溢出内容 |
| display: flow-root | 现代首选:专为触发 BFC 设计,无副作用 |
| display: flex / grid / inline-block | 切换显示类型的同时,也会创建 BFC |
| position: absolute / fixed | 脱离文档流的同时创建 BFC |
/* 现代 clearfix:无副作用,语义清晰 */ .row { display: flow-root; }
推荐只要目的是"包裹浮动子元素的高度",优先使用
display: flow-root,它是专门为此设计的属性值,不会像 overflow: hidden 那样意外裁掉子元素的阴影或下拉菜单。BFC 的实际用途
- 包裹浮动高度:如上所述,解决父元素高度塌陷。
- 阻止外边距合并:两个相邻块级元素的垂直 margin 默认会合并取较大值,把其中一个包裹进新的 BFC 可以阻止这种合并。
- 避免文字环绕浮动元素:给紧邻浮动元素的普通块级盒子触发 BFC,它会形成独立区域,不会被浮动元素挤压环绕,从而实现"两栏都不环绕文字"的整齐布局。
今天还需要 float 吗
在整体页面布局层面,float 已经被 Flexbox 与 Grid 完全取代——它们更直观、无需 clearfix、也没有高度塌陷的历史包袱。但 float 最初设计的场景——"文字环绕图片/首字下沉"——至今仍是它唯一无可替代的用途,Flexbox 和 Grid 都无法做到"内容围绕一个矩形环绕排列"的效果。