学习hasLayout

hasLayout是一个非常有必要理解的概念,大多IE下的显示错误,就是源于hasLayout。

什么是hasLayout?

hasLayout是Windows Internet Explorer(IE)渲染引擎的一个内部组成部分。在IE中,有两类元素:

  1. 元素对自身的内容进行计算大小和组织。
  2. 元素依赖于父元素来计算尺寸和组织内容。

当一个元素的hasLayout属性为true时,我们就说这个元素有一个布局,也就是这个元素对自己和可能的子孙元素进行尺寸计算和定位。

哪些元素拥有布局?

当一个元素有一个布局时,意味着这个元素需要花更多的代价来维护自身和里面的内容, 而不是依赖于祖先元素来完成这些工作。如果所有的元素都默认有布局,会对性能和内存使用上产生有害的影响。

以下元素默认拥有布局:

  • Images
  • Tables, TableRows, TableCells
  • HR
  • Input elements: text, button, file, select
  • Marquee
  • Framesets, Frames
  • Objects, applets, plugins
  • Absolute positioned elements
  • Floated elements
  • Inline-block elements
  • Filters (rotation, dropshadow, etc.)
  • Body (as well as HTML element in strict mode)

如何激发hasLayout?

  • Block level elements with width or height specified under strict mode
  • Any element with width/height specified under compat mode
  • Elements that have the Zoom property set
  • Elements that are in edit mode
  • Elements that host to a viewlinked behavior
  • Layout-flow is different from parent layout flow (rtl to ltr)
  • 设置position: absolute
  • 设置writing-mode: tb-rl
  • 设置float为left或right

zoom总是可以触发hasLayout,但是在IE5.0中不支持。

具有”layout”的元素如果同时display: inline,那么它的行为就和标准中所说的inline-block很类似了:在段落中和普通文字一样在水平方向和连续排列,受vertical-align影响,并且大小可以根据内容自适应调整。这也可以解释为什么单单在IE中内联元素可以包含块级元素而少出问题,因为在别的浏览器中 display: inline就是内联,不像IE一旦内联元素拥有layout还会变成inline-block。

hasLayout问题的调试与解决。

当网页在IE中有异常表现时,可以尝试激发hasLayout来看看是不是问题所在。常用的方法是给某元素css设定zoom: 1 。使用zoom: 1 是因为大多数情况下,它能在不影响现有环境的条件下激发元素的hasLayout。而一旦问题消失,那基本上就可以判断是 hasLayout 的原因。然后就可以通过设定相应的 css属性来对这个问题进行修正了。建议首先要考虑的是设定元素的width/height属性,其次再考虑其他属性。

对IE6及更早版本来说,常用的方法被称为霍莉破解(Holly hack),即设定这个元素的高度为1%。需要注意的是,当这个元素的 overflow属性被设置为visible时,这个方法就失效了。或者使用IE的条件注释。

对IE7来说,最好的方法时设置元素的最小高度为0(min-height:0;)。

hasLayout引起的常见bug。

  • IE6及更低版本的双空白边浮动(bug修复:display:inline;)
  • IE5-6的3像素偏移(bug修复:_height:1%;)
  • IE6的躲躲猫(peek-a-boo)(bug 修复:_height:1%;)

发表评论