CSS Handbook · 布局

第六章 / 6.5 浮动与 BFC

第六章 · 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 都无法做到"内容围绕一个矩形环绕排列"的效果。