我想大家在写CSS的时候应该都对清除浮动的用法深有体会,今天我们就还讨论下clearfix的进化史吧。
clearfix清除浮动
首先,我们常用的清除浮动是这样的。
.clear{clear:both;line-height:0;}
这是相当暴力有效的解决浮动的问题。但是这个用法有一个致命伤,就是每次清除浮动的时候都需要增加一个空标签来使用。这种做法如果在页面复杂的布局要经常清楚浮动的时候就会产生很多的空标签,增加了页面无用标签,不利于页面优化。
因此有很多大神就研究出了 clearfix 清除浮动的方法,直接解决了上面的缺陷,不需要增加空标签,直接在有浮动的外层加上这个样式就可以了。
起源
.clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } .clearfix { display: inline-table; } * html .clearfix { height: 1%; }
.clearfix { display: block; }
解释一下以上的代码:
起源代码可能也是很早期的时候了,再往后Mac下的IE5也发展到IE6了,各种浏览器开始向W3C这条标准慢慢靠齐了。所以就有了下面这个写法出现了。
.clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } * html .clearfix { zoom: 1; } /* IE6 */ *:first-child+html .clearfix { zoom: 1; } /* IE7 */
IE6 和 IE7 都不支持 :after 这个伪类,因此需要后面两条来触发IE6/7的haslayout,以清除浮动。幸运的是IE8支持 :after 伪类。因此只需要针对IE6/7的hack了。
在一个有float 属性元素的外层增加一个拥有clearfix属性的div包裹,可以保证外部div的height,即清除"浮动元素脱离了文档流,包围图片和文本的 div 不占据空间"的问题。
或者直接写成这样:
.clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } .clearfix{*zoom:1;}
但是对于很多同学这种优化程度代码还是不够给力,clearfix 发展到现在的两个终极版。
重构clearfix浮动
构成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:after { content:"\200B"; display:block; height:0; clear:both; } .clearfix {*zoom:1;}
解释下:content:"\200B";这个参数,Unicode字符里有一个“零宽度空格”,即 U+200B,代替原来的“.”,可以缩减代码量。而且不再使用visibility:hidden。
终极版二:
.clearfix:before,.clearfix:after{ content:""; display:table; } .clearfix:after{clear:both;} .clearfix{ *zoom:1;/*IE/7/6*/ }
这两个终极版代码都很简洁,终极版一和二都可以使用,以上代码都经过测试,大家赶紧用一下吧。