浮动与清浮动(二):清浮动

上一篇文章主要总结了浮动的两种方法:display:inline-blockfloat: left/right
第一种方法的主要局限是 IE7 不支持,且换行被解析成一个空格;而第二种方法更加可取。可是要记住一点:发明 float 的初衷是为了解决图文混排的问题,所以不可滥用(就像当年滥用 table 布局同样)。css

所谓“道高一尺,魔高一丈”,既然有浮动,那就必然有清浮动一说,矛盾是无处不在的。 html

为什么要有清浮动一说?按照我最简单的理解:浮动意味着脱离了文档流(层级提高“半层”),再也不按照原来的逻辑自上而自、从左到右排列元素,那么必然会对原来的元素布局产生影响,那么清浮动就是为了清除浮动带来的负面效果。好比下面一段代码:布局

.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 的样式添加这一属性:spa

.div2 {
		clear: both;
	}

结果发现 div2 在下一行显示,且换行未被解析成空格。在 Chrome44/FF39/IE-11 下面均测试经过,棒呆!看来 clear彷佛是清浮动的万能钥匙。(clear 是 CSS1 规定的属性).net

“塌陷”的本质

再来测试嵌套元素中的浮动效果:code

<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:htm

<div class="div3"></div>
.div3 {
		width: 600px;
		border: 10px solid #000;
		margin: 0 auto;
	}

在 FF39 中获得以下效果:
图片描述
也就是说,div 块级元素的内容为空时,其 Content Width/Height = 0。既然浮动元素再也不属于原来的父级元素,那父级元素里里就是空的,所以也就无所谓“塌不塌陷”一说了。借用一句禅语:“原本无一物,何处惹尘埃!”blog

总结上文,在结构(HTML)上,div2 属于 div1。可是,在形式(CSS)上,div2 不属于 div1。也就是说,这是结构和形式分离带来的矛盾。而清浮动,在某种意义上就是为了清除这一矛盾。图片

清浮动:父级元素

清浮动,无非从两方面着眼,一是父级元素自己,二是父级元素里的内容。
1、从父级元素自己来:
既然是因为父级元素和子级元素不在同一层级,那么能够给父级元素添加浮动:float/display:inline-block
图片描述
可是,这种方法的缺陷在于:改变了父级元素的样式,还要添加其余样式,增长了工做量,若是是多层嵌套的话,那势必要修改多个父级元素的样式,“子子孙孙无穷尽也”~

清浮动:子级元素

2、从子级元素考虑,也就是从父级元素里的内容考虑:
既然是由于父级元素 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私有属性)

关于浮动与清浮动,目前我的的总结基本就是这两篇了。