先记住这个答案
clear 的意思是「我这个元素的旁边不允许有浮动」。浏览器的做法是在这个元素上方插入一段空隙,规范里叫 clearance,让它的上边框刚好落在前面浮动元素的下外边缘之下。both 就是左浮动和右浮动都要避开,实际效果是移到两侧里更低的那个下面。整个过程只移动设置了 clear 的元素,浮动元素的位置不变。它也只看源码中排在它前面、并且处于同一个块格式化上下文里的浮动。
clear移动的是自己,不是浮动元素both等于同时避开左浮动和右浮动- 只看源码里在它前面、同一个 BFC 里的浮动
- 被清除的元素
margin-top常常像是失效了
左右两个不一样高的浮动
最常见的场景是左右两栏都浮动,高度不同,底部的页脚要排在两栏下面。
<div class="left" style="float: left; width: 40%; height: 100px; background: #bfdbfe;">左栏 100px</div>
<div class="right" style="float: right; width: 40%; height: 180px; background: #fde68a;">右栏 180px</div>
<footer style="clear: both; background: #d1fae5;">页脚</footer>
<!-- clear: left → 页脚顶部在 100px 处,右边还会被右栏挤着 -->
<!-- clear: right → 页脚顶部在 180px 处 -->
<!-- clear: both → 取更低的那个,也是 180px 处,左右都干净 -->去掉 clear 时,页脚是个普通块级元素,它会从容器顶部开始排,盒子本身其实钻到了两个浮动的下面,只有里面的文字绕开浮动挤到中间。加上 clear: both,浏览器计算左栏底部 100px 和右栏底部 180px,取较大值,把页脚整个推到 180px 以下。
clearance 带来的 margin 怪现象
理解了「clear 是往上面塞一段空隙」,就能解释一个很多人踩过的坑:给被清除的元素写 margin-top: 20px,想让它和浮动之间隔开一点,结果没有任何变化。
- 为什么 margin-top 像失效了
- 浏览器算 clearance 时,目标是让元素的上边框刚好贴到浮动底部。
margin-top本身算在这段距离里,clearance 会相应减少来补足,最后边框位置还是贴着浮动底部。只有当margin-top大到超过浮动的底部,才会看到效果。想要间距,更可靠的做法是给浮动元素加margin-bottom,或者给被清除的元素加padding-top。 另外,clearance 还会阻止被清除元素的margin-top和父元素的外边距合并,这也是有时候调外边距出现意外结果的原因之一。
容易答错的地方
- 说 clear 把浮动清除掉了
- 「清除浮动」这个说法容易让人以为浮动元素被删掉或者不再浮动了。实际上浮动元素原样不动,被移动的是写了
clear的那个元素。它清除的是「自己旁边的浮动」。 - 以为 clear 能管到任何浮动
clear只考虑源码里排在它前面的浮动,后面的浮动它不管。它也只看同一个块格式化上下文,也就是 BFC 里的浮动。如果浮动在一个overflow: hidden的子容器里,那个容器已经建立了新的 BFC,外面的clear就碰不到它。- 在 flex 容器里用 clear
- flex 和 grid 的子项上,
float和clear都不起作用。在这种布局里想换行,要用flex-wrap或者网格的行定义。
面试官还会怎么问?
clearfix 为什么这样写?
常见写法是 .clearfix::after { content: ''; display: block; clear: both; }。伪元素是容器里最后一个子元素,clear: both 把它推到所有浮动下面,而它是正常文档流里的块,容器的高度就得包住它,于是也就包住了浮动。display: block 是因为伪元素默认是行内的,行内元素上 clear 不生效。
浮动元素自己可以设置 clear 吗?
可以。浮动元素设置 clear: left 后,它会排到前面所有左浮动的下面,而不是接在它们右边。有时用这个办法让一排浮动的卡片从某一个开始另起一行。
现在还需要 clear 吗?
新布局基本用 flex 和 grid,已经很少手写浮动了。float 和 clear 如今主要用在「图片浮动、文字环绕」这类图文混排里,以及维护老项目时。父元素包住浮动可以直接用 display: flow-root,不再需要 clearfix。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。