[研究]闭合浮动元素的方法与差别
2008年3月4日
float属性在页面排版上非常有用,但是也带来很多问题。最常见的就是浮动元素的闭合问题。
如果一个没有设定高度的不浮动元素的子元素浮动,则该元素的高度不会包括浮动子元素的高度,而只会包含其内部不浮动元素的高度,因为浮动元素不属于常规流向,它脱离了文档流。因此如果要元素能够自动包含浮动子元素,则需要闭合浮动元素。
目前比较常用的有3种方法:
- 利用浮动子元素后的元素清除浮动(包括添加1个空的元素以清除浮动)。
- 使用:after伪元素,在元素最后插入清除。
- 为元素设定overflow属性除“visible”之外的值。
还有1个方法可以使元素自适应高度:
- 浮动元素,浮动的元素会包含浮动的后代元素。
下列代码,其显示如图1所示。
CSS:
p, div { margin: 5px; } .wrap { width: 440px; margin: 10px; clear: both; } .div1, .div2p { float: left; width: 80px; margin: 8px; +display: inline; }
XHTML:
<div class="wrap"> <div class="div1">div1,浮动</div> <div class="div2"> <p class="div2p">div2内p1</p> <p class="div2p">div2内p2</p> <p class="div2p3">div2内p3,不浮动</p> </div> <div class="div3">div3,不浮动</div> </div>
如果对.div2p增加CSS:
.div2p { ...... clear:left; }
由于“clear:left”含义为:不允许本元素左边有浮动框,而div1也是浮动元素,因此,p1和p2下移到了div1的下面,如图2所示。
而在IE中,整个div2都将下移到div1下,如图3所示。
由图3可以发现,虽然在图1中IE正确地显示了溢出的元素,但是,对于出发了layout的wrap,IE仍旧会扩展最外层的高度,以容纳浮动元素。
闭合浮动元素方法1
此时,div2的高度只包括其内未浮动元素的高度,因此使用第1种方法闭合浮动元素,为浮动元素后面的元素p3设定clear属性:
.div2p3 { clear:left; }
此时显示如图4所示,在IE中如图5所示。
(啊!伟大的IE,居然多出来与div2的margin一样多的间隙。= =b)
此时如果为div2增加左边距(原设定为margin:5px):
.div2 { ...... margin-left: 120px; }
则显示如图6所示,在IE中如图7所示。
至此的效果,是左右2栏布局常用的方法,左栏固定宽度,右栏不设定宽度以求能自适应。
闭合浮动元素方法2
尝试方法2,利用:after清除浮动:
.div2:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
显示效果如图8所示。(IE不支持,不用试了。= =b)
可以看到div2内的p3没有清除浮动,位置仍在div2的顶端。
增加div2的左边距,显示如图9所示。
.div2 { margin-left:120px; }
由此可见使用:after清除浮动,不适合于浮动元素后面还有不浮动元素的情况。
闭合浮动元素方法3
尝试方法3,使用overflow属性:
.div2 { overflow:auto; +height:100%; /* 针对ie6 */ }
此时,最热闹的情况出现了:
首先,div2的宽度收缩到div1的右边了,也许这正好是期望的结果?
更热闹的在后面,增加div2的margin-left:
.div2 { margin-left:120px; }
都是margin-left惹的祸,去掉margin-left:
.div2 { margin-left: 0; }
由此可见,overflow还是有很大局限性的。
浮动
div2浮动,浮动元素的高度会包含其内部的浮动元素。
这种方法的局限性就是,div2浮动后宽度会被压缩,因此必须给它一个宽度值,但是这样就无法自适应宽度。
.div2 { float: left; } .div3 { clear: both; }
效果如图18所示。
div2的浮动,还会造成wrap的高度问题,因此需要div3清除浮动。
由这个例子可以发现,由于div2的浮动,其内的p元素清除浮动,并没有受到div1的影响,因此,解决由于前2种方法中p1和p2下降到div1的高度之下的方法之一,可以将p1和p2外面套1个浮动的div,当然这可能影响到结构,还需要结合具体情况来决定。