跳到主要内容

谈谈浮动(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 个关键效果

  1. 脱流(out of normal flow):浮动元素不再占据普通文档流的位置。
  2. 绕排(text wrap):后续行内内容会围绕浮动元素排版。
  3. 塌陷(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(能用但要说清副作用)

overflowvisible 时也会建立 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(不生效)。

易错点/坑

  • 把“清除浮动”理解成“删除 float 属性”:实际是通过 clear 或 BFC/clearfix 来处理浮动对布局的影响。
  • overflow: hidden 一把梭:容易把阴影、下拉菜单、tooltip 等给裁剪掉。
  • 用浮动硬写两列/三列布局:现代更推荐 flex/grid,可读性与可维护性更好。

速记要点(可背诵)

  • float:脱流 + 绕排 + 可能导致父容器高度塌陷。
  • clear:让“我”避开前面的浮动(常用 clear: both)。
  • 解决父容器塌陷:优先 display: flow-root,其次 clearfix,再其次 overflow(注意裁剪副作用)。