上一篇文章主要总结了浮动的两种方法:display:inline-block
和 float: left/right
。
第一种方法的主要局限是 IE7 不支持,且换行被解析成一个空格;而第二种方法更加可取。但是要记住一点:发明 float 的初衷是为了解决图文混排的问题,因此不可滥用(就像当年滥用 table 布局一样)。
所谓“道高一尺,魔高一丈”,既然有浮动,那就必然有清浮动一说,矛盾是无处不在的。
为何要有清浮动一说?按照我最简单的理解:浮动意味着脱离了文档流(层级提升“半层”),不再按照原来的逻辑自上而自、从左到右排列元素,那么必然会对原来的元素布局产生影响,那么清浮动就是为了清除浮动带来的负面效果。比如下面一段代码:
.div1 {
float: left;
width: 200px;
height: 200px;
background-color: red;
}
.div2 {
width: 300px;
height: 300px;
background-color: blue;
}
<div class="div1">div1</div>
<div class="div2">div2</div>
结果就会导致 div1 遮挡住一部分 div2,当然可以通过其他方法来解决这个问题,如设置 div2 的 position,但这是逃避问题,而不是解决问题(清浮动)。以下是我总结的清浮动常用方法:
clear
clear
是为清浮动而生,清浮动并不是并浮动的元素清除掉,而是指不允许指定元素的某个方向上出现浮动元素。clear 的常用值有:left/right/both/none,通常用 both
。
给上文代码中 div2 的样式添加这一属性:
.div2 {
clear: both;
}
结果发现 div2 在下一行显示,且换行未被解析成空格。在 Chrome44/FF39/IE-11 下面均测试通过,棒呆!看来 clear
似乎是清浮动的万能钥匙。(clear 是 CSS1 规定的属性)
“塌陷”的本质
再来测试嵌套元素中的浮动效果:
<style type="text/css">
body {
margin: 0;
padding: 0;
}
.div1 {
border: 10px solid #000;
margin: 20px auto;
width: 600px;
}
.div2 {
background-color: red;
width: 400px;
height: 300px;
float: left;
}
</style>
<div class="div1">
<div class="div2"></div>
</div>
结果在 FF39 中得到了如下的显示效果:
去掉 div2 的 float:left
,显示如下:
可以看出,float
属性使 div2 的父级元素 div1 高度变为0,俗称“塌陷”。很多人从float对父级元素的影响来解释“塌陷”,按照我个人的理解,如下:
我们回归 float 的本质,浮动会导致当前元素脱离文档流,提升自身层级“半层”,也就是说浮动的元素也就不再属于原来的层级,在这里来说,从显示效果(样式)上看: div2 也就不再是 div1 的子元素。
在这个例子中,再添加 div3:
<div class="div3"></div>
.div3 {
width: 600px;
border: 10px solid #000;
margin: 0 auto;
}
在 FF39 中得到如下效果:
也就是说,div 块级元素的内容为空时,其 Content Width/Height = 0。既然浮动元素不再属于原来的父级元素,那父级元素里里就是空的,因此也就无所谓“塌不塌陷”一说了。借用一句禅语:“本来无一物,何处惹尘埃!”
总结上文,在结构(HTML)上,div2 属于 div1。但是,在形式(CSS)上,div2 不属于 div1。也就是说,这是结构和形式分离带来的矛盾。而清浮动,在某种意义上就是为了清除这一矛盾。
清浮动:父级元素
清浮动,无非从两方面着眼,一是父级元素本身,二是父级元素里的内容。
一、从父级元素本身来:
既然是由于父级元素和子级元素不在同一层级,那么可以给父级元素添加浮动:float
/display:inline-block
:
但是,这种方法的缺陷在于:改变了父级元素的样式,还要添加其他样式,增加了工作量,如果是多层嵌套的话,那势必要修改多个父级元素的样式,“子子孙孙无穷尽也”~
清浮动:子级元素
二、从子级元素考虑,也就是从父级元素里的内容考虑:
既然是因为父级元素 div1 中没有内容导致的,那可以考虑在 div1 里面加点料:
方法1:
.clear{
clear: both;
height: 0; // 解决 IE6 下最小高度19px的问题
font-size: 0; // 解决 IE6 下最小高度19px的问题
}
<div class="clear"></div>
经测试,IE7(包括)以上,加注释的两行不写其实也没关系。
方法2:
<br clear='both'>
IE6 以上全兼容,关于<br clear='both'>
这一行,可以查阅 w3c 中文网的解释。
方法3:
方法1和方法2的缺陷在于,需要在<HTML>中添加内容。为了改变样式而添加内容,这违背了结构与样式分享的原则。
因此,可以考虑采用伪类:after
,并结合方法2:
.clear {
zoom: 1; // zoom 是 IE6 私有属性
}
.div1:after {
content: '';
display: block;
clear: both;
}
<div class="div1 clear">
<div class="div2"></div>
</div>
带注释的一行是专门针对 IE6 的小 hack,因为刚装了 Win10,IETester 好像出了点问题不能用了,因此没测试 IE6 下的兼容性,IE7 及以上均测试通过。
关于 zoom,可以阅读这一篇文章:CSS中不为人知Zoom属性的使用介绍(IE私有属性)
关于浮动与清浮动,目前个人的总结基本就是这两篇了。