最近研究浮动,看到一篇文章(http://www.iyunlu.com/view/css-xhtml/55.html)很不错,将这篇文章按照自己的思路梳理了一下
浮动float是网页布局的常客,可这位客人有时并不”友好”.在使用浮动的时候,我们惊奇的发现,网页后面的内容与浮动元素重合了.这,得想办法解决掉!
为什么会产生这种现象?
先来一段代码看看这种现象:
css:
/*包含框*/
.wrap{
width: 1000px;padding: 20px;border: 1px solid #999;
}
/*浮动框*/
.floater{
float: left;background: #777;width: 100%;height: 50px;
}
/*包含框下面的元素*/
.footer{
margin: 10px;width:1022px;background: #CCC;
}
html:
<div class="wrap">
<div class="floater"></div>
</div>
<div class="footer">未清除浮动的情况</div>
展现效果为:
下面元素与上面的float元素重合了,而上面浮动元素的父元素高度则缩小了.原因很简单:浮动元素是脱离文档流的,也就是说父元素在计算高度的时候不会将浮动元素的高度计算在内,故而父元素的高度就会产生坍塌,使得后面内容与浮动元素产生重合.
如何解决?
触发BFC
上面说了,重合的原因是父元素坍塌造成的,而父元素坍塌是因为计算高度时未将浮动元素计算在内,因此我们只要使父元素计算浮动时将浮动元素计算在内就可以解决这个问题.可怎么让父元素计算高度一并包含浮动元素?BFC可以解决这个问题.
css中有一个渲染机制--BFC(Block Formatting Context,即块格式化上下文),BFC作为一种渲染机制,可以使得元素内部元素的布局和定位就和外部元素互不影响.简单的说,具有形成BFC的元素在计算高度时,会将浮动元素一并算入.所以要想父元素计算高度包括浮动元素,只要触发父元素的BFC机制就可以了.
下面说说BFC触发的几种条件:
- float的值不为none
- overflow的值不为visible
- display的值为inline-block、table-cell、table-caption
- position的值为absolute或fixed
只要在浮动元素父元素中设置触发BFC的样式即可清除浮动.下面举一些清除浮动的例子:
父元素设置overflow
<div class="wrap" style="overflow: hidden;*zoom:1;"> <div class="floater"></div> </div> <div class="footer"> 父元素使用overflow:hidden清除浮动,需要使用*zoom:1 </div> <div class="wrap" style="overflow: auto;*zoom:1;"> <div class="floater"></div> </div> <div class="footer"> 父元素使用overflow:auto清除浮动,需要使用*zoom:1 </div>
设置table
<div class="wrap" style="display: table;"> <div class="floater"></div> </div> <div class="footer"> 父元素使用display: table;清除浮动,需要使用*zoom:1 </div> <div class="wrap" style="display: table-cell;"> <div class="floater"></div> </div> <div class="footer"> 父元素使用display: table-cell;清除浮动,需要使用*zoom:1 </div>
父元素浮动
<div class="wrap" style="float: left;"> <div class="floater"></div> </div> <div class="footer" style="float: left;"> 父元素浮动清除浮动,子元素也要浮动 </div>
注意:使用overflow,table清除浮动的时候,因为ie6/7浏览器的兼容性不能处理,需要添加zoom:1样式.zoom:1的原理是使用zoom时会触发元素的hasLayout,这使得元素有自己的布局,元素会对自己的子元素重新进行计算和定位.
使用clear
css里面提供了一个清除浮动的样式--clear,使用该属性可以清除元素的浮动.
clear: left | right | both | none | inherit;
对clear值的解释:
- left: 元素左边不允许出现浮动元素
- right: 元素右边不允许出现浮动元素
- both: 元素两边都不允许出现浮动元素
- none: 默认值,元素两边运行出现浮动元素
- inherit: 继承,从父元素继承clear的值
使用clear属性的元素,因为不允许元素周围出现浮动元素,因此该元素会排列到浮动元素的后面.下面举一些使用clear清除浮动例子:
添加额外的标签,并为该标签设置clear: both属性
<!--添加一个br标签--> <div class="wrap"> <div class="floater"></div> </div> <br clear="both" /> <div class="footer"> 使用br并添加clear="both"清除浮动 </div> <!--添加一个额外div--> <div class="wrap"> <div class="floater"></div> </div> <div style="clear: both;"></div> <div class="footer"> 使用div并添加clear="both"清除浮动 </div>
注意:使用
<br>
标签时clear是作为该标签的属性添加的,而不是样式.使用after伪元素
css:
.clearfix:after{ content: "."; display:block; visibility: hidden; height: 0px; clear: both; } .clearfix{ *zoom:1; }
html:
<div class="wrap clearfix"> <div class="floater"></div> </div> <div class="footer"> 使用after伪元素清除浮动 </div>
**注意:**ie下不支持after伪元素,为了兼容要使用zoom: 1
更好的方案:
“零宽度空格”
Unicode字符中的字符U+200B ,这个字符本身是不可见的,所以我们可以省略掉
visibility:hidden
.clearfix:after { content:"200B"; display:block; height:0; clear:both; } .clearfix { *zoom:1; }
A new micro clearfix hack
.cf:before,.cf:after { content:""; display:table; } .cf:after { clear:both; } .cf { /*For IE6/7 (trigger hasLayout)*/ zoom:1; }
这个方案里面使用了before伪元素,是为了防止BFC使上面元素的margin-bottom和下面元素的margin-top垂直外边距叠加
总结
清除浮动主要通过触发BFC和clear两种方式,同时需要考虑ie的兼容性来触发hasLayout.根据BFC的触发条件,我们可以得出几种消除浮动的方法:设置overflow不为visible,设置table或者table-cell,设置父元素浮动.使用clear时可以通过添加额外的标签,或者使用after伪元素(设置伪元素为"."
而不是""
是为了防止firefox浏览器中产生额外的空隙).考虑到ie兼容性,可以通过zoom: 1
触发hasLayout来从而使元素重新计算布局和定位从而实现消除浮动.