原文地址http://msdn.microsoft.com/en-us/library/bb250481(v=vs.85).aspx
作者:Markus Mielke (Microsoft Corporation)
2005-08-30
一些IE下的bug可以通过激活元素的"layout"(一种IE内置的数据结构)来得到解决(例如, dimensional bug fixes和 Holly hack),但是为什么要给元素加上一个"layout"的数据结构,实际上大多数用户并不了解。这篇文章解释了当一个元素拥有"layout"之后会有什么变化,以及设置"layout"的原因。
首先,我们从分析元素的类型开始,页面中通常有两类元素:
总体来说,在DHTML中,大部分元素属于第一种元素,DHTML引擎不支持元素对自身尺寸和内容进行计算,虽然像div和p这样的元素在文档流和优先级规则中拥有自己的定位,但是其内部元素的布局还是依赖与其最近的拥有布局的祖先元素(通常是body)来进行。这些元素通过祖先元素的布局来进行自身内部复杂的尺寸计算和内容编排。
Note:拥有布局影响力的元素不一定是元素直接的父元素,有可能是其祖先元素,放弃让每一个元素拥有布局的好处在于其简洁性,从而提高了页面性能。
一般来说,如果某个元素拥有自己的“领地”,需要在领地内展现特定的信息和功能,并且这种信息和功能会影响到其领地内容的位置和渲染,那它即会拥有一个Layout。例如:
这里列举了一些已知的在不产生视觉变化的情况下让元素拥有haslayout属性的场景,当你看到或使用它们时,请注意它们所带来的影响(感谢Ingo chao及列表的收集者们)
场景1:floating
见下方代码:
<div style="float:left; border: 2px solid red"> 123</div>
<span style="border: 2px solid blue">
The quick brown fox jumped over the lazy dog's back.
The quick brown fox jumped over the lazy dog's back.
The quick brown fox jumped over the lazy dog's back.
The quick brown fox jumped over the lazy dog's back.
The quick brown fox jumped over the lazy dog's back.
</span>
执行代码,我们将会看到
如果我们让span元素拥有'Layout'会产生神马效果?
<style>
.gainlayout {zoom: 1;}
</style>
<span class="gainlayout" style="border: 2px solid blue">
场景2 自动布局
<div style="position: absolute; background:red">
<div>
123
</div>
</div>
执行代码,我们将会看到:
如果我们让子元素div拥有'layout'会产生什么效果?
<style>
.gainlayout {zoom: 1;}
</style>
<div style="position: absolute; background:red">
<div class="gainlayout">
123
</div>
</div>
场景三 相对定位
现在我们来看一看如何利用'haslayout'来处理bug
<div style="position: relative; border: 2px solid blue">
<div style="float:left; border: 2px solid red">
<img style="position: relative; border: 2px solid green; width:100px; height:100px"
src="slider.jpg">
</div>
</div>
我们希望在IE下达到以下效果
理想效果应该是:
但是我们会惊奇地发现,IE6下是这样子的:
这是为什么呢?
注意: 你可能也会注意到那两条合并起来的蓝色边框并没有像原先预想的那样穿过红线,这一点需要我们注意,元素一旦浮动起来即拥有了布局,就像例子中一样,浮动的div并不会受旁边的div的蓝色边框的影响。而在这种场景下,是IE6的一个bug
一般解决这类bug的方法是让原先没有布局的元素"拥有Layout"。
<style>
.gainlayout {zoom: 1;}
</style>
<div class="gainlayout" style="position: relative; border: 2px solid blue">
结果如下:
优点:
缺点:
在这个场景中,你不需要做太多修改(除了可以移除不必要的"position:relative"语句),我们并不反对使用"haslayout"的方法去解决Ie6的bug,只是想给大家解释一下触发元素"haslayout"后会造成的影响。从长远来看,这些bug都会被修复掉,即使不在IE7,也会在IE后续的版本中。
我试着向大家解释一些IE内核Trident有关'haslayout'的内部工作机制以及它带来的副作用,并列举了哪些元素本身即自带内置布局,哪些元素可以通过触发获得布局。最后,我讨论了元素获得布局后会带来的影响并列举了一些典型案例。
理想状态下,用户不应该也不需要知道这个特性,因为它主要用于解决IE内部的一些css的布局问题,但是,它如今已经成为一种修复IE6下布局bug的有效手段。另外,IE的这个特性并未与css规范产生冲突,而是用来更加规范地实现css特性,鉴于这个考虑,我很乐意为'haslayout'属性的理解和运用做一些贡献。
感谢Web Standards Group(WaSP) 对本文的支持和反馈,特别感谢Dean Edwards 和 Chris Wilson的审校,感谢Holly Bergevin, Ingo Chao, Bruno Fassino, John Gallant, Georg S?rtun, and Philippe Wittenbergh积极参与讨论本文的创作,本文希望能为社区有关'haslayout'的讨论作出贡献
Markus Mielke 是微软Internet Explorer 团队的一名项目经理