IE下hasLayout知多少?
hasLayout是IE特有的一个属性。很多的ie下的css bug都与其息息相关。在ie中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织内容。当一个元素的hasLayout属性值为true时,它负责对自己和可能的子孙元素进行尺寸计算和定位。虽然这意味着这个元素需要花更多的代价来维护自身和里面的内容,而不是依赖于祖先元素来完成这些工作。
haslayout是怎么来的?
为了解决这个问题,微软的天才coder决定去修理他们的这个古老的引擎,因此haslayout这个属性就诞生了。每个元素都有haslayout这个属性去设置true或者false,如果它设置成了true,它就不得不去渲染它自己,因此元素不得不扩展去包含它的流出的内容。例如浮动或者很长很长的没有截断的单词,如果haslayout没有被设置成true,那么元素得依靠某个祖先元素来渲染它。这就是很多的ie bugs诞生的地方。
haslayout触发机制
特别注意的是,hasLayout在IE 8及之后的IE版本中已经被抛弃,所以在实际开发中只需针对IE 8以下的浏览器为某些元素触发hasLayout。一个元素触发hasLayout会影响一个元素的尺寸和定位,这样会消耗更多的系统资源,因此IE设计者默认只为一部分的元素触发hasLayout (即默认有部分元素会触发hasLayout),这部分元素如下:
[codesyntax lang="php"]
body and html table, tr, th, td img hr input, button, file, select, textarea, fieldset marquee frameset, frame, iframe objects, applets, embed
[/codesyntax]
如何触发 hasLayout
除了IE默认会触发hasLayout的元素外,Web开发者还可以使用特定的CSS触发元素的hasLayout。通过为元素设置以下任一CSS,可以触发hasLayout(即把元素的hasLayout属性设置为true)。
[codesyntax lang="php"]
float:(left或right) position:absolute display:inline-block width:(除auto外任何值) height:(除auto外任何值) zoom:(除normal外任意数值,包括设置为效果等同于normal的1也有效)
[/codesyntax]
另外,一些CSS在IE7下亦能触发hasLayout。
[codesyntax lang="php"]
min-width:(包含0在内的任意值) max-width:(除none外任意值) min-height:(包含0在内的任意值) max-height:(除none外任意值) overflow:除了visible以外的值(hidden,auto,scroll) position:fixed
[/codesyntax]
很多IE6造成的诡异BUG都是hasLayout捣的鬼,很是可恶。如果IE有些很难解释的问题,第一件要做的事情就是让该元素在IE6/7下触发一次hasLayout,最常用的就是*zoom:1;的方式。怎样在IE6下触发hasLayout让块状元素实现display:inline-block的效果呢?请看下面示例代码:
div{
display
:inline-
block
;
_display
:
inline
;*zoom:
1
;}
总结:其实依据合理的语义化,恰当的文档流,正确的标准化所生产出来的页面,在各个公司出品的标准渲染的浏览器下,一般并不会存在太多兼容性的问题的。
一般如果是因为layout而引起的显示不符期望效果的话,在ff下会表现正常,而在ie下会出现错误。这个时候可以尝试触发父容器及其中的子容器的haslayout属性,通常可以通过加上zoom: 1;来调试。直到找到了产生问题的元素,再进行针对性的修正。最好的办法是对这个元素设置尺寸属性。但是,有时不便指定尺寸属性的情况下,就只能寻找替代方案了。对于ie7 ,最好的办法是设置最小高度属性为0;这个技术是无害的,因为0本来就是这个属性的初始值。而且没有必要对其他浏览器隐藏这个属性。而对于ie6和更早版本中触发一个元素hasLayout的方法是在overflow属性是visible的情况下设置这个元素的高度属性为1%,然后对其他浏览器隐藏这个设置。这种技术就是著名的Holly hack。