从清除浮动(clear float)谈拥有布局(has layout)与块级格式化范围(block formatting context)
float是网页布局中都要使用的css属性,他为我们灵活布局提供了方便,但同时浮动太多会带来很多麻烦,所以我通常的做法是使用float完后,马上清除他。float的本质是脱离的正常的html文档流,就是由于他脱离的文档流才出现了很多麻烦。
清除浮动(我更喜欢叫闭合浮动元素)的最简单的方法就用<div style=”clear:both;”></div>加入空的标签,但是这种不够语义化,也显得不是很灵活,每次都要加额外的html。于是有人就想到css里面有一个:after的,这样就不需要加入额外的html了,完全由css完成,于是就有了下面这段比较经典的css代码:.clear:after{
content:"
";
display:block;
height:0;
clear:both;
visibility:hidden;}
简单的解释一下吧,用after产生的内容是个空格,先display:block,然后高度为0,不让他影响布局,clear:both就是清除浮动啦,隐藏和height:0差不多就是不要影响布局。但是这么做只对支持:after的浏览器(比较多了ie8、ie9、firefox3.X、opera、chrom、safari)有作用,要是不支持怎么办呢?
不支持after的浏览器也不是很多了,最常用的可能就只有ie6、ie7了,对于ie6、和ie7的解决就是加一个height:1%;就ok了。好了,貌似所有主流的浏览器的问题都解决了。赶快进入正题。
为什么ie6、7加了个height:1%就ok了?是为了让其has layout。那么has layout是什么呢?
其实haslayout 是Windows Internet Explorer7以下渲染引擎的一个内部组成部分。在InternetExplorer7以下中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织内容。为了调节这两个不同的概念,渲染引擎采用了 hasLayout 的属性,属性值可以为true或false。当一个元素的 hasLayout属性值为true时,我们说这个元素有一个布局(layout)。当一个元素有一个布局时,它负责对自己和可能的子孙元素进行尺寸计算和定位。简单来说,而不是依赖于祖先元素来完成这些工作。通过 IE Developer Toolbar 可以查看 IE 下 HTML元素是否拥有haslayout,拥有 haslayout的元素,通常显示为“haslayout = -1”。
这里的has layout就是对自己和可能的子孙元素进行尺寸计算和定位来决定父元素的高度,也就是父元素适应了里面内容的高度,这回大家就明白为什么加入一个height:1%的原因了,当然也可以加入其它的属性使其has layout,如width等。当然加float也可以(float也可以触发layout),但不推荐,不要用floa来清除浮动,这样float又会产生一个浮动,那样你的页面会很乱,初学者很容易犯得一个错误。
其实清除浮动的本质就是产生一个块级格式化范围,它会自动清除内部的浮动,首先强调一下块级格式化范围不是ie6、7所独有的,而是属于css的一种现象。关于边距重叠大家应该都比较清楚,两个普通的div边距,如果是两个正数,那么他们实际的边距是取他们中最大的,如果有一个是负数就把两个值加起来,这些就是由于没有产生块级格式化的原因。如果产生了块级格式化他们就将不会共享边距,他们的会有各自的边距,他们的实际边距就会相加。
那么当一个元素产生了块级格式化一个没有会是什么情况呢?
除了ie6、7认为只要有一个产生了块级格式化就不应该和其他共享边距,其他的浏览器(ie8 ie9 Firefox chrom Safari opera)都是认为可以边距共享的。我不知道这是不是又和ie的haslayou有关。
由于float会产生块级格式化范围,所以很多刚开始学css的人就会用float来产生块级格式化范围来清除浮动和避免边距重叠。但float很恶心啊!
关于has layout和block formatting context我这里先不多说了,以后会对他们单独解释。最后回归清除浮动,对于任何浏览器只要产生块级格式化范围就可以了,对于has layout浏览器要让浮动的父级元素has layout。知道这两点以后各种清除浮动的方法就很好懂了。