谈谈浮动(float)和清除浮动(clear / clearfix)
面试速答(30 秒版 TL;DR)
float会让元素进入「浮动布局」:脱离普通文档流,父元素在height: auto时通常不会被浮动子元素撑开(常见“高度塌陷”)。float不是“完全不影响别人”:它会导致后续的行内内容(文字)绕排;后续块级元素也会在布局时“避让”浮动(除非建立 BFC 或使用clear)。clear的语义是:让当前元素的这一侧不允许贴着浮动元素,必要时把当前元素“顶到”浮动元素下方(常用clear: both)。- “清除浮动”在面试里通常指两类问题:
- 让后续元素不再绕排/不再被浮动影响:用
clear或建立 BFC。 - 让父容器包含浮动子元素(解决高度塌陷):优先
display: flow-root,其次 clearfix(::after { clear: both }),再其次overflow: hidden/auto(有副作用)。
- 让后续元素不再绕排/不再被浮动影响:用
心智模型:浮动的 3 个关键效果
- 脱流(out of normal flow):浮动元素不再占据普通文档流的位置。
- 绕排(text wrap):后续行内内容会围绕浮动元素排版。
- 塌陷(parent collapse):父元素如果只包含浮动子元素,且未建立 BFC/未清除,
height: auto往往算出来是 0(或小于预期)。
float 到底“做了什么”?
1)浮动元素如何摆放(你需要会描述,不必背规范)
把它理解为:浏览器会尽量把浮动盒子“贴到”包含块的左/右边,并在当前行能放下就放下,放不下就换到下一行继续尝试;同时后续的行内内容会绕开它可占据的区域。
常见现象:
- 多个
float: left会从左到右依次排列,空间不够就换行。 - 给图片
float: left,文字会自然环绕图片,这是 float 仍然有价值的场景。
2)为什么会“高度塌陷”?
因为浮动元素不在普通文档流里,父元素的 height: auto 计算高度时,只看“仍在流里”的子元素;如果父元素的子元素全是浮动,就容易出现父容器高度看起来为 0。
复现用例(看边框是否把浮动子元素包住):
<div class="card">
<div class="left"></div>
<div class="right"></div>
</div>
<p class="after">后续内容</p>
.card {
border: 2px solid #333;
}
.left,
.right {
float: left;
width: 120px;
height: 60px;
background: #ddd;
}
.right {
margin-left: 12px;
}
此时 .card 的边框往往不会包住两个子块(高度塌陷)。
clear:清除“谁的影响”?
很多同学把 clear 理解成“把浮动清掉”,更准确的说法是:
clear是写在后续元素上的,它会让这个元素在排版时避开前面的浮动。- 常用:
clear: both,表示左右两侧都不允许挨着浮动。
示例:让页脚不和前面的浮动同排,直接换到下面。
<div class="media">
<img class="avatar" src="/img/avatar.png" alt="" />
<p>这是一段会绕排图片的文字...</p>
</div>
<div class="footer">footer</div>
.avatar {
float: left;
width: 80px;
height: 80px;
margin-right: 12px;
}
.footer {
clear: both;
}
注意点(高频追问):
clear通常只对块级盒子有意义;如果你把它写在span这类默认行内元素上,经常会“看起来不生效”,需要先让它生成块级盒子(如display: block)。
清除浮动的常见方案(面试回答建议按推荐顺序说)
1)display: flow-root(现代首选)
让父容器创建一个新的 BFC(Block Formatting Context,块级格式化上下文),它会把浮动子元素的高度算进来,从而自然“包含浮动”。
.card {
display: flow-root;
border: 2px solid #333;
}
优点:语义清晰、副作用小。
注意:旧版 IE 不支持(如果面试官问兼容性,补一句“老项目用 clearfix 兜底”即可)。
2)clearfix(通用经典方案)
核心思路:给父容器的末尾插入一个“看不见的块”,让它 clear: both,从而把父容器高度撑起来。
.clearfix::after {
content: "";
display: block;
clear: both;
}
使用:
<div class="card clearfix">...</div>
3)overflow: hidden/auto(能用但要说清副作用)
overflow 非 visible 时也会建立 BFC,从而包含浮动。
.card {
overflow: auto;
}
副作用:
- 可能裁剪阴影、弹出层等溢出内容(
hidden更明显)。 auto可能引入滚动条(取决于内容)。
4)额外空标签清除(不推荐,但要认识)
<div class="card">
<div class="left"></div>
<div class="right"></div>
<div style="clear: both"></div>
</div>
缺点:污染结构(语义差),维护成本高;面试里一般说“理解即可,不建议在工程里用”。
典型题 & 标准答法
Q1:什么是浮动?它的特点是什么?
答题要点:
float让元素脱离普通文档流,进入浮动布局。- 会产生文字绕排效果,常用于图文混排。
- 容器只包含浮动子元素时可能高度塌陷,需要 BFC/clearfix 等手段处理。
Q2:clear 和 clearfix 有什么区别?
答题要点:
clear是后续元素用来避开前序浮动的属性,解决的是“不要和浮动同排/不要绕排”。- clearfix 是父容器用来“包含浮动子元素”的技巧,解决的是“高度塌陷/父容器包不住浮动内容”。
Q3:为什么 overflow: hidden 能清除浮动?
答题要点:
- 因为它会触发父元素建立 BFC;在 BFC 的规则下,计算高度时会把浮动子元素纳入,从而包住浮动。
- 但它可能裁剪溢出内容,所以通常不如
display: flow-root语义清晰。
常见追问
float现在还用吗?- 做布局基本被 flex/grid 替代;但图文混排(文字绕图片)场景依然常见。
- 为什么我写了
clear: both还是不生效?- 常见原因:元素是行内盒子、或元素是绝对定位、或你在 flex/grid item 上用
float/clear(不生效)。
- 常见原因:元素是行内盒子、或元素是绝对定位、或你在 flex/grid item 上用
易错点/坑
- 把“清除浮动”理解成“删除 float 属性”:实际是通过
clear或 BFC/clearfix 来处理浮动对布局的影响。 - 用
overflow: hidden一把梭:容易把阴影、下拉菜单、tooltip 等给裁剪掉。 - 用浮动硬写两列/三列布局:现代更推荐
flex/grid,可读性与可维护性更好。
速记要点(可背诵)
float:脱流 + 绕排 + 可能导致父容器高度塌陷。clear:让“我”避开前面的浮动(常用clear: both)。- 解决父容器塌陷:优先
display: flow-root,其次 clearfix,再其次overflow(注意裁剪副作用)。