有关.clearfix的一些事

<Category: 前端设计> 查看评论

一,什么是.clearfix

很多网站都讲到一个盒子清除内部浮动时可以用到.clearfix。

1 .clearfix:after {
2   content: " ";
3   display: block;
4   clear: both;
5   height: 0;
6 }
7 .clearfix {
8   zoom: 1;
9 }
1 <div class="clearfix">
2   <div class="floated"></div>
3 </div>

上面的代码就是.clearfix的定义和应用,简单的说下.clearfix的原理:

  • 在IE6, 7下zoom: 1会触发hasLayout,从而使元素闭合内部的浮动。
  • 在标准浏览器下,.clearfix:after这个伪类会在应用到.clearfix的元素后面插入一个clear: both的块级元素,从而达到清除浮动的作用。这时的代码相当于:
    1 <div>
    2   <div class="floated"></div>
    3 </div>
    4 <div style="clear: both"></div>

二,.clearfix的弊端

在上面的代码中可以看到,抛开IE6, 7不谈,.clearfix在标准浏览器下插入了一个clear: both的元素,这样很可能清除掉不必要的浮动。举例来说明:

01 <!DOCTYPE html>
02 <html>
03 <head>
04   <title>Demo</title>
05   <style type="text/css">
06     html, body { padding: 0; margin: 0; }
07     ul { margin: 0; padding: 0; } 
08   
09     .clearfix:after {
10       content: " ";
11       display: block;
12       clear: both;
13       height: 0;
14     }
15     .clearfix {
16       zoom: 1;
17     }
18   
19     .left-col {
20       background: red;
21       float: left;
22       width: 100px;
23       height: 300px;
24     }
25     .right-col {
26       margin-left: 100px;
27     }
28     .menu {
29       border: 1px solid #000;
30     }
31     .menu li {
32       float: left;
33       display: block;
34       padding: 0 1em;
35       margin: 0 1em 0 0;
36       background: #ccc;
37     }
38     .placeholder {
39       background: yellow;
40       height: 400px;
41     }
42   </style>
43 </head>
44 <body>
45   <div class="left-col">
46   </div>
47   <div class="right-col">
48     <ul class="menu">
49       <li>Menu Item</li>
50       <li>Menu Item</li>
51       <li>Menu Item</li>
52       <li>Menu Item</li>
53       <li>Menu Item</li>
54       <li>Menu Item</li>
55     </ul>
56     <div class="placeholder"></div>
57   </div>
58 </body>
59 </html>

上面的代码构成一个两列布局的页面。注意.menu这个菜单设置了边框,但是由于.menu的li元素是左浮动的,导致.menu没有高度,于是可以用.clearfix来清除.menu内部的浮动。代码如下:

1 <ul class="menu clearfix">
2   <li>Menu Item</li>
3   <li>Menu Item</li>
4   <li>Menu Item</li>
5   <li>Menu Item</li>
6   <li>Menu Item</li>
7   <li>Menu Item</li>
8 </ul>

但是应用完.clearfix后,在标准浏览器下页面变得很乱,这是因为.clearfix:after把.left-col的浮动也给清除掉了。

三,重构.clearfix

在遭遇到上面的错误之后,分析一下除了.clearfix:after这种方式之外还有没有别的方法清除元素内部的浮动。答案是有的,在白话Block Formatting Contexts这篇文章中提到过构成Block Formatting Context的元素可以清除内部元素的浮动。那么只要使.clearfix形成Block Formatting Context就好了。构成Block Formatting Context的方法有下面几种:

  • float的值不为none。
  • overflow的值不为visible。
  • display的值为table-cell, table-caption, inline-block中的任何一个。
  • position的值不为relative和static。

很明显,float和position不合适我们的需求。那只能从overflow或者display中选取一个。因为是应用了.clearfix和.menu的菜单极有可能是多级的,所以overflow: hidden或overflow: auto也不满足需求(会把下拉的菜单隐藏掉或者出滚动条),那么只能从display下手。

我们可以将.clearfix的display值设为table-cell, table-caption, inline-block中的任何一个,但是display: inline-block会产生多余空白,所以也排除掉。剩下的只有table-cell, table-caption,为了保证兼容可以用display: table来使.clearfix形成一个Block Formatting Context,因为display: table会产生一些匿名盒子,这些匿名盒子的其中一个(display值为table-cell)会形成Block Formatting Context。这样我们新的.clearfix就会闭合内部元素的浮动。下面是重构之后的.clearfix。

1 .clearfix {
2   zoom: 1;
3   display: table;
4 }

四,总结

在IE6, 7下面只要是触发了hasLayout的元素就可以清除内部浮动了。而在标准浏览器下面清除元素内部浮动的方法有很多,除了.clearfix:after这种方式,其余的方法无非就是产生新的Block Formatting Context以达到目的。如果可以做到在什么条件下用哪种方法,我认为这样就足够了……

作者:周明智

本文来自: 有关.clearfix的一些事

您或许也会喜欢:

  • 14款非常有用的 CSS 网格系统生成工具(0)
  • 瀑布布局的JavaScript实现方式(0)
  • 45个非常奇妙的 CSS3 特性应用示例(0)
  • 支付宝前端开源其CSS样式库方案 - Alice(0)
  • 抛弃 CSS Hacks 后的浏览器兼容方案(0)
  • 分享16个优秀的 CSS3 表单开发教程(0)
  • 前端设计中的浏览器CSS Hack汇总(0)
  • 三十款CSS样式选择器代码(0)
  • CSS 忍者:安全的 CSS hacks 秘籍(0)
  • 圆角头像的重构优化(0)