CSS清除浮动

浮动布局是 CSS 布局中最早也是常用的布局之一,兼容性好,使用广泛。 元素浮动在页面设计中一般主要有两个作用。 第一个作用是: 文字环绕图片效果 。

目录
  1. 浮动布局
  2. 清除浮动
    1. 添加 overflow 等属性创建 BFC
    2. 父元素也浮动起来
    3. 添加非浮动的清除元素
  3. 总结

浮动布局#

浮动布局是 CSS 布局中最早也是常用的布局之一,兼容性好,使用广泛。

元素浮动在页面设计中一般主要有两个作用。

第一个作用是:文字环绕图片效果

<style>
  section {
    border: 1px solid blue;
    margin: 0 0 10px;
  }
  img {
    float: left;
  }
  p {
    margin: 0;
  }
</style>
<section>
  <img src="./images/iwatch.png" />
  <p>
    Apple Watch 是苹果公司于2014年9月10日公布的一款智能手表,有Apple
    Watch、Apple Watch Sport 和Apple Watch Edition 三种风格不同的系列。Apple
    Watch 采用人造蓝宝石水晶屏幕与Force Touch触摸技术,有多种颜色可供选择。Apple
    Watch Sport 共10款:起价为2588元,最高2988元。Apple Watch
    共20款,起价为4188元,最高8288元。Apple Watch Edition
    共8款,起价为74800元,最高126800元。三个系列都于2015年4月10日接受预定,4月24日起正式发售。首发地区包括中国大陆、中国香港、美国、日本、英国、法国、加拿大、澳大利亚。Apple
    Watch 于2015年4月10日开放试戴预约。
  </p>
</section>

image.png

第二个作用是:使得原来上下堆叠的块状元素变成左右并列,实现分栏布局

<style>
  .container div {
    height: 300px;
  }
  .left {
    float: left;
    width: 300px;
    background: red;
  }
  .right {
    float: right;
    width: 300px;
    background: green;
  }
  .main {
    background: yellow;
  }
</style>
<article class="container">
  <div class="left">left</div>
  <div class="right">right</div>
  <div class="main">这是浮动布局的中间部分</div>
</article>

image.png

但是,浮动虽然使得元素脱离文档流,但是没有脱离文本流,所以它会占据一定的空间位置,使得紧跟其后的元素也会在空间允许的情况下向上和向左浮动起来,填充浮动元素剩余的空间位置。这样会打乱原先的布局,使得页面混乱。

<style>
  section {
    border: 1px solid blue;
    margin: 0 0 10px;
  }
  img {
    float: left;
  }
  p {
    margin: 0;
  }
  footer {
    border: 1px solid red;
  }
</style>
<section>
  <img src="./images/iwatch.png" />
  <p>It's fun to float.</p>
</section>
<footer>
  Here is the footer element that runs across the bottom of the page.
</footer>

image.png

上面的代码中图片增加了浮动属性float:left,使得图片向左浮动起来,但是后面的footer元素竟然也跟着浮动起来了,紧跟在p元素后面,这就不是我们想要的结果。

这时候就需要清除浮动,清除浮动主要有以下几种方法。

清除浮动#

添加 overflow 等属性创建 BFC#

给父元素添加overflow: hidden,使得其成为 BFC,这样就可以把浮动的子元素包裹起来,因为 BFC 和把外面所有的元素都隔离开来,使得后面的footer元素不会受到父元素里面子元素浮动的影响,还是按照原来的上下堆叠排布。注意除了overflow属性外,还有很多属性可以使得元素成为 BFC 。CSS3 中新增display:flow-root可以是使得元素成为 BFC。

<style>
  section {
    border: 1px solid blue;
    margin: 0 0 10px;
    overflow: hidden;
  }
  img {
    float: left;
  }
  p {
    margin: 0;
  }
  footer {
    border: 1px solid red;
  }
</style>
<section>
  <img src="./images/iwatch.png" />
  <p>It's fun to float.</p>
</section>
<footer>
  Here is the footer element that runs across the bottom of the page.
</footer>

image.png

父元素也浮动起来#

给父元素也添加浮动float: left,使得父元素也浮动起来,成为 BFC,这样父元素会把浮动的子元素包裹起来,但是父元素因为只占了有限的空间,所以后面的footer元素在空间的允许的情况下也会浮动起来,填充到右边的空间位置上,所以还需要让父元素把上面的空间全部占领了,添加宽度width:100%,这样footer元素只能排在下面了,清除浮动成功。

补充,表面上是没什么关系,但是实际上可能并不完美的。因为这样虽然清除了子元素图片造成的浮动,但是又添加了父元素的浮动属性。虽然设置了width:100%,占据了上面的所有空间,下面的元素不会再跑上来,不会影响上面的布局。但是如果后续宽度有变化的话,浮动元素后面的元素还是会跑上来的。所以最好给footer元素也添加属性clear:left来清除浮动,这样会更好一点。

<style>
  section {
    border: 1px solid blue;
    margin: 0 0 10px;
    float: left;
    width: 100%;
  }
  img {
    float: left;
  }
  p {
    margin: 0;
  }
  footer {
    border: 1px solid red;
    clear: left;
  }
</style>
<section>
  <img src="./images/iwatch.png" />
  <p>It's fun to float.</p>
</section>
<footer>
  Here is the footer element that runs across the bottom of the page.
</footer>

image.png

添加非浮动的清除元素#

添加非浮动元素来清除浮动,有两种方法。

添加一个非浮动的子元素

在父元素后面添加一个非浮动的子元素,即在浮动子元素的后面添加一个非浮动的兄弟元素,样式属性设置为clear:left,这是属性专门用来清除浮动的,可以切断后面元素的浮动。因为父元素一定会包含没有脱离文档流的子元素,所以父元素会把这个“清除浮动的元素”包裹进来,也把它前面的浮动元素也包裹进来了。这样,就不会影响到父元素之外的footer元素了。

<style>
  section {
    border: 1px solid blue;
    margin: 0 0 10px;
  }
  img {
    float: left;
  }
  p {
    margin: 0;
  }
  .clear {
    clear: left;
  }
  footer {
    border: 1px solid red;
  }
</style>
<section>
  <img src="./images/iwatch.png" />
  <p>It's fun to float.</p>
  <div class="clear"></div>
  <!-- 非浮动元素 -->
</section>
<footer>
  Here is the footer element that runs across the bottom of the page.
</footer>

image.png

使用伪元素

设置父元素的伪元素after为非浮动元素,用来切断后面元素的浮动,其实原理和上面的是一样,只是用法不一样而已。父元素包裹了这个没有脱离文档流的伪元素,同样也包含了伪元素前面的浮动元素。注意:伪元素是位于该元素内容的最后面的一个真实元素(它是父元素里面最后一个子元素,而不是父元素后面的兄弟元素)。给父元素设置一个类clearfix,专门只用来清除浮动,设置这个类的伪元素afterclear:both用来清除浮动,另外设置一些属性把它隐藏掉,从而又不会影响其他元素,它只用来清除浮动,没有别的作用。

<style>
  section {
    border: 1px solid blue;
    margin: 0 0 10px;
  }
  .clearfix::after {
    content: " ";
    display: block;
    clear: both;
    height: 0;
    visibility: hidden;
  }
  img {
    float: left;
  }
  p {
    margin: 0;
  }
  footer {
    border: 1px solid red;
  }
</style>
<section class="clearfix">
  <img src="./images/iwatch.png" />
  <p>It's fun to float.</p>
</section>
<footer>
  Here is the footer element that runs across the bottom of the page.
</footer>

第两种添加伪元素的方法使用非常广泛,设置一个类用来清除浮动,随时调用,灵活方便。但是有时候因为伪元素存在兼容性的问题,也会使用到第一种方法。

总结#

这三种清除浮动的方法各有优缺点,需要根据实际情况,灵活使用。

  • 添加特殊属性形成 BFC 使得浮动清除,代码最少。但是在有些特殊场景不适合使用,比如overflow:hidden在下拉菜单的时候不适用。另外,无故添加一个overflow属性也会使得人觉得费解,不明其用意。也可以添加display:flow-root属性,这是最新的用来创建 BFC 的属性,但是因为是新的属性,对于一些旧版浏览器会存在兼容性的问题。

  • 使父元素浮动不能在自动外边距居中的元素中使用。

  • 添加伪元素为不浮动元素在一些低版本的浏览器中(比如 IE8 以下浏览器)是不支持的。而在父元素最后的子元素中添加不浮动元素时,在一些动态列表或者复杂交互的时候,可能需要借助 JavaScript 代码来实现。