父元素高度塌陷是 float 脱离文档流的必然结果,解决关键是创建 BFC;display: flow-root 最干净,overflow: hidden 兼容性最好但会裁剪溢出内容,::after 伪元素 clearfix 是老浏览器折中方案,flex/grid 可彻底规避该问题。

父元素高度塌陷不是 bug,是 float 脱离文档流的必然结果;解决的关键不是“清浮动”,而是让父容器重新包含浮动子项——即创建新的 BFC。
用 display: flow-root 最干净
这是现代浏览器(Chrome 64+、Firefox 59+、Safari 15.4+)原生支持的 BFC 创建方式,专为解决这类问题设计。
-
display: flow-root不改变盒模型语义,不裁剪溢出内容(比如下拉菜单、tooltip、绝对定位子元素) - 无需伪元素、无需额外 DOM、无 clear 逻辑干扰
- 如果项目兼容性允许(不需支持 IE 或老版 Safari),应作为首选
示例:
.container {
display: flow-root;
}
.container > div {
float: left;
width: 200px;
height: 100px;
}
用 overflow: hidden 兼容性最好
IE6 就支持,至今仍是上线项目最稳妥的选择,但副作用明确。
立即学习“前端免费学习笔记(深入)”;
-
overflow: hidden或overflow: auto都会触发 BFC,使父容器重新包裹浮动子项 - ⚠️ 若子元素有
position: absolute且超出父容器边界,会被裁剪(常见于弹层、气泡提示) -
overflow: visible无效,它不触发 BFC
不要把它当成“清除浮动”的技巧,它是 BFC 的副产品。
用 ::after 伪元素实现 clearfix
当需要兼容老浏览器,又想避免 DOM 污染时,这是折中方案。
- 必须写
content: "",否则伪元素不渲染 - 推荐用
display: table(比block更稳妥,避免 margin 堆叠问题) - 不能写在浮动子元素外部,必须作用于父容器本身
标准写法:
.clearfix::after {
content: "";
display: table;
clear: both;
}
为什么 clear: both 单独加在子元素上没用?
很多人把 clear: both 加在浮动元素自己身上,或加在父容器 CSS 里——这完全无效。
-
clear只对**自身所在元素**生效,作用是“避开上方浮动”,不是“通知父容器包含我” - 加在浮动子元素上:它只是把自己下推,父容器依然不知道它存在
- 加在父容器样式里:
clear不是布局属性,父容器没有“浮动”可清,CSS 解析器直接忽略
真正起作用的,永远是那个被插入到浮动流**末端**、并参与文档流的清除节点(真实元素或伪元素)。
最容易被忽略的一点:float 本就不是为整体布局设计的。如果项目允许,直接换成 display: flex 或 display: grid,浮动属性会被忽略,高度自适应天然成立——这时候你根本不需要考虑“撑开父元素”。


















