IE的hasLayout属性

介绍

这篇文章是已经有的 hasLayout 文章的总结。
更新:hasLayout 已经从IE8标准模式中移除,但是在IE-7兼容版本中依然存在。

为什么会 hsa Layout?

微软的IE使用相当落后的表现引擎(毫无疑问,因为IE基于Mosaic)。在古老的使用table的时代,几乎所有的元素(除了inline内容)都是一个盒子,没有办法让内容逃出单元格(teble cell)的禁锢,对单元格来说,它则逃不出table的手掌心……
许多年过去了,微软开始适应古老的Trident(三叉戟)引擎去使用CSS。然而CSS却改变了古老的引擎以来的基础的状态——主要是一个矩形包含了所 有的内容。CSS允许内容浮动(overflow)出容器。这种情况发生在内容浮动(float)或者内容太宽超出了容器的大小。

hsaLayout 怎么来的?

微软“天才的”程序员决定用一种非常奇怪的方法修复他们古老的引擎。这也就是 hasLayout “特性”的由来。每一个元素都将 hasLayout 设置成了 true 或者false。如果设置成了true——元素就是一个有责任自我表示的盒子。因此,元素可以扩展,从而包含溢出的内容,就像float或者没有换行的非 常非常长的句子。如果hasLayout设置成了false ——元素不会自我表示,而是会将表示的工作交给已经设置了 hasLayout 的祖先元素。这就是大多数的IE bug的来源。
当然 hsaLayout “属性”并不是一个 CSS 属性,你不能像这样设置他 {hasLayout:true;} 否则事情就变的简单了。一个 hasLayout 设置为 true 的元素通常指 having layout(有布局),而 hasLayout 设置为 false 的指 not having layout(没有布局)。

Ok,老实交代,你们哪个 Has Layout?

下面这些元素默认设置了“layout”

1
2
3
4
5
6
7
<html>, <body>
<table>, <tr>, <th>, <td>
<iframe>, <embed> (不规范), <object>, <applet>
<img>
<hr>
<input>, <button>, <select>, <textarea>, <fieldset>, <legend>
<marquee> (永远不要用这个标签,不规范的而且会被忽略)

这个列表或许不完全。这些元素中的大多数都从来没有在微软的文档中提及。当然,要测试一个元素是否设置了“layout”或者没有设置非常的简单。例如,看下面的代码:

1
2
3
<div id="menu">
    ...
</div>

要确定这个<div>的 “hasLayout” 属性,我们可以在地址栏运行这段代码:
javascript:alert(menu.currentStyle.hasLayout)
在运行了上面这行代码之后弹出框中会显示 true 或者 false,表明这个ID属性为 menu 的 has Layout 值。如果你看到 undefined,可能意味着你输入了一个错误的ID,检查你的拼写。

给我 Layout! 谢谢!

设置hasLayout为true,换句话说设置 layout(giving layout),比起将它设置为false相对简单。
下面的属性/值可以设置一个元素的layout:

1
2
3
4
5
6
7
position: absolute
float: left right
display: inline-block
width: 除了auto的值
height: 除了auto的值
zoom: 除了normal的值 (看下面的说明 )
writing-mode: tb-rl (看下面的说明 )

对于IE7来说,一些新的属性可以设置“layout”:

1
2
3
4
5
6
7
overflow: hidden or scroll or auto
overflow-x: hidden or scroll or auto
overflow-y: hidden or scroll or auto
min-width: any value other than auto
max-width: any value other than auto
min-height: any value other than auto
max-height: any value other than auto

虽然在IE7-兼容模式下还存在 hasLayout(目的很明显),但是微软最后终于在IE8中干掉了 hasLayout。
你或许对 zoom 和 writing-mode 属性还不熟悉。这两个都是微软私有的 CSS 扩展。他们仅仅对IE起作用而且不能通过验证(validate)。因此,我强烈地建议你把他们放进IE的条件注释(conditional comments)里面去。当然,writing-mode 属性已经出现在CSS3的技术报告中 (CSS3 Technical Report),zoom属性有一天或许也会加入,但是就我现在所知还没有。
Zoom 明显地放大(zoom)一个元素。例如,zoom:2 将把元素放大到两倍,zoom:1 将显示元素正常的大小,因此这也是为什么我个人认为 zoom:1;是通过应用到IE的条件注释(conditional comments)里面去来设置一个元素的 “layout” 的最有用的一个属性。因为他不会对元素产生其他的影响。
Writing-mode 属性是一个被CSS3建议加入的属性,用来确认文字如何被书写(written)。“tb-rl” 值指“从上到下,从右到左”,这种排版格式在东亚使用。西方的排版描述成“从左到右,从上到下”,就可以被设置为 “lr-tb”
设置 display:inline-block 然后再在另外的规则设置中设置回原始的 display 属性值不会移除 layout,当你不使用其他的属性是,这个小诡计(trick)可以用来设置 layout 而不使用IE的条件注释(conditional comments)。下面是这个诡计的例子:

1
2
div { display: inline-block; }
div { display: block; } /* 分别在两段 css 块中设置 */

属性 overflow-x 和 overflow-y 同样进入了 CSS3 技术报告中,虽然现在还不能很好的支持。
设置私有 contenteditable 属性同样也个以给一个元素设置 “layout”。

1
<p contenteditable="true">so lame</p>

你绝对不要用这个方法来设置 hasLayout,这里写它只是为了信息完整性的目的。contenteditable 不仅是微软的一个私有属性(因此他不会被 validate )而且允许用户编辑元素的内容很有可能让用户感到迷惑。
“hasLayout 属性”是只读的,你不能够直接通过 javascript 来设置他。

我根本就不想要它!

这样一切都解决了吗?没有,因为由于 hasLayout 设置为 true 也会遇到 bug。由于 hasLayout 是只读的,除了
使用 属性/值 把它设置成 true 之外,没有办法把它设置成 false。这个规则的一个例外是前面提到的 display:inline-block, 把它设置为其它值不会把 hasLayout 设为 false。
你不能设置具有默认的 “layout” 属性的元素的 hasLayout 为 false。幸运的是,大多数的IE的大多数的 bug 是由于元素没有 layout 引起的。

到处都是bug!

根据我的经验我敢说 IE 80%的 bug 都是由于一个元素 没有设置 “layout” 导致的。Disappearing Content Bug 是 layout bug的一个很好的例子。
而由于一个元素 having layout 引起的 bug 并不常见。下面是其中一个:
This is not one line
在IE中这行自会被显示在一行中。看起来这个bug产生的原因是由于

with hasLayout set to true does not properly inherit the white-space property from the parent element. Setting white-space: pre on the

itself or making sure it does not have “layout” fixes the bug.
IE的 hasLayout bug 经常很奇怪的自己冒出来。如果IE做了一些你无法用语言解释的事情——你要做的第一件事可能就是个给这个元素设置 “layout”。

原文地址:https://www.cnblogs.com/yingzi/p/2572741.html