Menu

CSS float 浮动与 clear:让文字环绕图片

float 把元素推到一侧,让文字环绕在它周围,就像杂志排版里的配图。本文讲解 float 的 left、right 和 inline-start,clear 的用法,父元素为什么会在浮动元素周围塌陷、display: flow-root 如何解决,以及为什么页面布局不再使用浮动。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

float 的作用

float 把元素推到容器的一侧,让后面的文字环绕在它周围:

浮动方块上的外边距让文字不会紧贴着它。这段间距只能靠外边距来控制;文字本身无法设置朝向浮动元素的外边距。

可选的值

值效果
none(默认)不浮动
left推到左边缘
right推到右边缘
inline-start推到行的起始端:英文里是左边,阿拉伯语或希伯来语里是右边
inline-end推到行的末尾端

inline-start 和 inline-end 跟随书写方向,所以用它们搭建的布局在从右到左的页面上能正确镜像。浮动元素还会变成块级元素:display: inline 会被转换成 block,因此即使是 span 或 img,width 和 height 也会生效。

让图片浮动在文字中

最经典的用法:文章里放一张图片,文字环绕着它。两侧各浮动一张:

clear:停止环绕

clear 的意思是“从这一侧之前所有浮动元素的下方开始”。把它用在不应该排在浮动元素旁边的元素上,比如下一节的标题:

第一个标题挤在了浮动元素旁边,第二个则从它下方开始。clear 可以取 left、right、both、inline-start、inline-end 和 none。

父元素塌陷与 flow-root

浮动元素脱离了正常文档流,所以子元素全部浮动的容器在文档流中没有任何内容,高度塌陷为零。它的背景和边框最后只剩浮动元素上方的一条细线:

display: flow-root 会创建一个新的块级格式化上下文(BFC),它总是会包住自己的浮动元素。较老的代码用“clearfix” 达到同样的效果:

.clearfix::after {
  content: "";
  display: block;
  clear: both;
}

overflow: hidden 或 auto 也能包含浮动元素,副作用是会裁剪内容;参见 overflow。

浮动不是用来布局的

在 flexbox 和 grid 出现之前,整个页面布局都是用浮动的分栏搭起来的,到处都是 clearfix 和宽度计算。那个时代已经过去了:浮动无法居中,无法让各栏等高,内容尺寸一变就会错乱。行和列请用 display: flex 或 display: grid,float 只用来让文字环绕某个元素。如果想让图片居中而不是让文字环绕它,参见 如何让图片居中。

沿形状环绕

shape-outside 让文字沿着一个形状环绕,而不是沿着浮动元素的矩形。它只对浮动元素有效:

.avatar {
  float: left;
  width: 120px; height: 120px;
  border-radius: 50%;
  shape-outside: circle(50%);
  margin-inline-end: 16px;
}

常见错误

  • 父元素高度为零。 它的子元素全都浮动了。加上 display: flow-root。
  • 用浮动做分栏或导航。 请用 flexbox 或 grid。
  • 以为有 float: center。 它并不存在。用 flexbox、grid 或 margin: 0 auto 来居中。
  • 浮动元素后面的内容在不该环绕时环绕了。 给它加上 clear: both,或者把浮动元素和文字放进一个 flow-root 容器。
  • 在多语言网站上使用物理方向的 left 和 right。 改用 inline-start 和 inline-end,让布局在从右到左的语言中能够镜像。

常见问题

CSS 中的 float 有什么作用?

它把元素从正常文档流中取出,推到容器的左边缘或右边缘。排在它后面的文字和行内内容会环绕在它周围。

clear 有什么作用?

clear 让元素移到指定一侧之前所有浮动元素的下方:clear: left、clear: right 或 clear: both。想让内容不再排在浮动元素旁边,就用它。

为什么浮动元素的父元素高度为零?

浮动元素脱离了正常文档流,所以只有浮动子元素的父元素在文档流中没有内容,于是高度塌陷。给父元素加上 display: flow-root,它就会撑开,把浮动元素包含进来。

clearfix 是什么?

一种让父元素包含其浮动子元素的技巧,传统写法是一个带 clear: both 的 ::after 伪元素。如今在父元素上写一行 display: flow-root 就能达到同样效果。

布局应该用 float 吗?

不应该。在 flexbox 和 grid 出现之前,人们用浮动来做分栏。布局请用 flexbox 或 grid,float 只留给它本来的用途:让文字环绕图片或引文。

Coddy 编程语言插图

和 Coddy 一起学编程

开始