7.3 CSS 浮动(float)

最不确定的属性

float 属性会给渲染带来很大的可变性,包括一些意外的错误。

float 可能是最难于掌握的一个CSS属性,它的行为可以是有趣的,意想不到的,神奇的。 原因是在所有的定位属性中,浮动属性是对其周边元素产生最大影响的那个。

换句话说,把一个元素设置成浮动,不只是改变它自己的行为,也会改变它的祖先、兄弟、后代元素

float 属性可以被设置为下面3个值:

  • leftright 设置靠左浮动或靠右浮动。
  • none 清除浮动。

什么时候使用浮动

浮动元素的设计本意可类比Word文档中的对象(比如图片)自适应周边文本区域,视觉效果就是这个对象好像在文本区域中浮动,而文本环绕在四周一样。

我们结合下面的图文(段落中内嵌图片)例子来解释使用浮动的意图:

<p>
  <img src="//placehold.it/150x150">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lacus nulla, convallis eu tellus quis, pharetra ullamcorper lacus. Etiam varius ornare neque, in porta nunc dictum vel. Aliquam placerat congue orci eu convallis. Vivamus tempor leo ac libero suscipit, sit amet finibus massa auctor.
</p>

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lacus nulla, convallis eu tellus quis, pharetra ullamcorper lacus. Etiam varius ornare neque, in porta nunc dictum vel. Aliquam placerat congue orci eu convallis. Vivamus tempor leo ac libero suscipit, sit amet finibus massa auctor.

问题是,由于图片高度通常比文本要大得多,图片嵌入到一行里,导致所在行被撑高,如上面图片的高度是150px。

实际上我们想让文本环绕在图片周围,一来节约显示空间,二来更为美观。浮动属性就是用来实现这个想法的。

img{ float: left;}

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lacus nulla, convallis eu tellus quis, pharetra ullamcorper lacus. Etiam varius ornare neque, in porta nunc dictum vel. Aliquam placerat congue orci eu convallis. Vivamus tempor leo ac libero suscipit, sit amet finibus massa auctor.

如上所示,图片元素被推到左边,而后续文本元素环绕在周围:

  • 首先,文本被推到图片右边,紧邻前面的图片。
  • 然后,一旦图片下方出现空间时,文本马上填补上去。

如果文本不够长呢?

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

可以看到图片溢出(overflow)了,因为它比容器要高。而且更糟糕的是图片甚至挤压了我们正在阅读的这一行文本。

这个特意设计的布局错误揭示了为什么浮动元素行为是不可预测的:甚至会破坏它的父元素以外元素的布局。

原因是 float: left 把图片从正常文档流中抽离了出来,父元素p只包含了文本的高度,并不会考虑图片的高度。

Float = block

浮动元素会自动被应用一个 display: block 规则,和块元素行为接近(除了占据整行宽度):

  • 你可以为浮动元素设置宽和高
  • 如果没有设置高度,那么元素的高度就是行高。
  • 如果设置了 width: 100%,那么看起来就和块级元素一样。

清除缓存

clear 属性值可用来把元素推离浮动区域。它只能用于块元素。

<p>
  <img src="//placehold.it/150x150">
  <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
</p>
img{ float: left;}
span{ clear: left; display: block;}

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

浮动使得文本紧邻图片,而清除浮动的代码 clear: left 将把文本推到图片下方。

我们还可以看到不设置浮动和清除浮动的效果并不相同,不设置任何浮动时,图片和文本在同一行,而清除浮动时,图片在单独的一行。