属性
·下列 CSS 属性和取值将会让一个元素获得 layout:
position: absolute 绝对定位元素的包含区块(containing block)就会经常在这一方面出问题。 float: left|right 由于 layout 元素的特性,浮动模型会有很多怪异的表现。 display: inline-block 当一个内联级别的元素需要 layout 的时候往往就要用到它,这也可能也是这个 CSS 属性的唯一效果——让某个元素拥有 layout。“inline-block行为”在IE中是可以实现的,但是非常与众不同: IE/Win: inline-block and hasLayout 。 width: 除 “auto” 外的任意值 很多人遇到 layout 相关问题发生时,一般都会先尝试用这个来修复。 height: 除 “auto” 外的任意值 height: 1% 就在 Holly Hack 中用到。 zoom: 除 “normal” 外的任意值 (MSDN) MS专有属性,无法通过校验。 不过 zoom: 1 可以临时用做调试。 writing-mode: tb-rl (MSDN) MS专有属性,无法通过校验。
·在 IE7 中,overflow 也变成了一个 layout 触发器:
overflow: hidden|scroll|auto 这个属性在之前版本 IE 中没有触发 layout 的功能。 overflow-x|-y: hidden|scroll|auto overflow-x 和 overflow-y 是 CSS3 盒模型中的属性,尚未得到浏览器的广泛支持。他们在之前版本IE中没有触发 layout 的功能。
·另外 IE7 的荧幕上又新添了几个 haslayout 的演员,如果只从 hasLayout 这个方面考虑,min/max 和 width/height 的表现类似,position 的 fixed 和 absolute 也是一模一样。
position: fixed ./. min-width: 任意值 就算设为0也可以让该元素获得 layout。 max-width: 除 “none” 之外的任意值 ./. min-height: 任意值 即使设为0也可以让该元素的 haslayout=true max-height: 除 “none” 之外的任意值 ./.
以上结论借助 IE Developer Toobar 以及预先测试得出。
有关内联级别元素
对于内联元素(可以是默认即为内联的比如 span 元素,也可以是 display: inline 的元素)
·width 和 height 只在 IE5.x 下和 IE6 或更新版本的 quirks 模式下触发 hasLayout 而对于 IE6,如果浏览器运行于标准兼容模式下,内联元素会忽略 width 或 height 属性,所以设置 width 或 height 不能在此种情况下令该元素具有 layout。
·zoom 总是可以触发 hasLayout,但是在 IE5.0 中不支持。
具有“layout” 的元素如果同时也 display: inline ,那么它的行为就和标准中所说的 inline-block 很类似了:在段落中和普通文字一样在水平方向和连续排列,受 vertical-align 影响,并且大小可以根据内容自适应调整。这也可以解释为什么单单在 IE/Win 中内联元素可以包含块级元素而少出问题,因为在别的浏览器中 display: inline 就是内联,不像 IE/Win 一旦内联元素拥有 layout 还会变成 inline-block。
脚本属性 hasLayout
我们这里称 hasLayout 为“脚本属性”是为了和我们熟知的 CSS 属性相区别。
注意一旦一个元素拥有了 layout,就没有办法再将其设成 hasLayout = False 了。
hasLayout-property 可以用来检测一个元素是否拥有 layout:举个例子,如果它的 id 是“eid”,那么只要在
IE5.5+ 的地址栏里输入 javascript: alert(eid.currentStyle.hasLayout) 即可检测它的状态。 IE的 Developer Toolbar 可以实时检查一个元素的当前样式;如果 hasLayout 是 true ,那么它的值显示为 “-1”。 我们可以通过实时修改一个元素的属性将“zoom(css)”设置为“1”来触发 hasLayout 以便调试。
另外一个需要注意的是“layout”会影响脚本编程。如果一个元素没有“layout”,那么clientWidth/clientHeight 总是返回0。这会让一些脚本新手感到困惑,而且这和 Mozilla 浏览器的处理方式也不一样。不过我们可以利用这一点在 IE5.0 中检测“layout”:如果 clientWidth 是零那么这个元素就没有 layout。
CSS hacks
下面用于触发 haslayout 的 hack 已经经过 IE6 及以下版本测试。今后版本的IE有可能会对此做不同处理。如果新版本浏览器发布我们会重新整理这部分内容。 John Gallant 和 Holly Bergevin 在2003年发布的 Holly hack :
/* \*/ * html .gainlayout { height: 1%; } /* */
·可以让 IE5+ 的任意元素获得 layout,除了标准兼容模式 IE6 中的内联元素。 ·一般都很有效,除了在某些极少情况下,需要用 height:0 或者 1px 更好一些。 ·和 overflow: hidden 不相容,除非在 IE6 的标注兼容模式下(因为这时如果父元素没有定高,那么height: 1% 会被变回 height: auto)。
或者我们可以用 underscore hack:
.gainlayout { _height: 0; }
另外,更具有向后兼容性的方法是使用 条件注释(conditional comments):
<!--[if lte IE 6]> <style> .gainlayout { height: 1px; } </style> <![endif]-->
在条件注释中链接一个专门对 IE/Win 做修正的外部样式表文件,也不失为一个安全有效的好方法:
<link rel="stylesheet" href="allbrowsers.css" type="text/css" /> <!--[if lte IE 6]> <link rel="stylesheet" href="iefix.css" type="text/css" /> <![endif]-->
我们更倾向于使用 height: 0 和 1px —— 并主张始终使用 height 除非它和别的什么东西冲突 (overflow: hidden)。对于取值,我们则倾向于避免 1% ,因为它可能会(虽然很少)引起一些问题。
height 不能应用于标准模式下的内联元素。在这种情况下我们可以用 display: inline-block 或 zoom: 1。
我们曾看过一些把 Holly hack 真的当作 holy(神圣的) hack 盲目使用的情况,比如对浮动元素使用或者对已经具有特定宽度的元素也使用这个 hack。要记住这个 hack 的目的不是要给某个元素加一个高度,而只是要触发 hasLayout = True 而已。
不要给所有元素设置 layout:* {_height: 1px;}。所谓过犹不及,获得 layout 不等于获得灵丹妙药,它只是用来改变渲染模式。
Hack整理
但是浏览器总是会变的,我们需要面对很多问题,比如一些依赖 IE6 的 bug 所做的 hack 会在 IE7 或更高版本的新浏览器中因 bug 修复而失效(甚至有害)的问题;比如新版本浏览器中类似的布局 bug 依然存在但用于 hack 的过滤器比如 * html 却不能正常工作的问题。这种情况下,MS专有属性 zoom 就可以考虑使用了。
<!--[if lt IE 7]><style> /* IE 6 + IE5.5 + IE5.0 所用样式*/ .gainlayout { height: 0; } </style><![endif]--> <!--[if IE 7]><style> .gainlayout { zoom: 1;} /* 或者其他任何以后可能需要的东西 */ </style><![endif]-->
·zoom: 1; 可以让 IE5.5+ 的任何元素(包括内联元素)获得 layout,但是在 IE5.0 中无效。 ·没有其他附带效果(内联元素会变成 inline-block,这个当然)。 ·如果需要通过验证,应该用条件注释将 zoom 隐藏起来。
其实当我们考虑到“向后兼容”时是很自相矛盾的,我们强烈建议页面设计者回过头看一下自己页面中用的到的明显的或是不明显的“hacks”,并用条件注释针对不同浏览器重新处理以保万无一失。
关于IE Mac 的小问题
IE Mac 和 windows 下的 IE 是完全不同的两个东西,它们各自拥有自己的渲染引擎,IE Mac 就全然不知“hasLayout”(或contenteditable)所谓何物。相比之下 IE Mac 的渲染引擎要更标准兼容一点,比如 height 就是被当作 height 处理,没有别的效果。因此针对“hasLayout”的 hacks 和别的解决方法(特别是通过使用 height 或 width 属性的)往往对 IE Mac 来说是有害的,所以需要对其隐藏。更多的关于 IE Mac 相关的问题可以在 IE Mac, bugs and oddities pages 找到。
MSDN 文档
MSDN 中涉及到 hasLayout 这个 MS 属性的地方寥寥无几,而具体解释 layout 和 IE 渲染模型之间关系的则少之又少。 在IE4的时候,除了未经绝对定位也未指定宽高的内联元素,几乎所有元素都有某种 layout(MSDN)。在这种早期的layout概念中,像 border, margin, padding 这些属性被称作“layout属性”,它们是不能应用到一个简单的内联元素上的。换句话说,“拥有layout”就可以粗略理解成:“可以拥有这几个属性”。
MSDN 上仍然使用 layout 属性这种说法, 只是含义变了,它们和拥有 layout 的元素已经没有什么关系了。在 IE5.5 中方才引入了 MS 的这个专有属性 hasLayout,也只是某种内部的标志位而已。
在 IE5.5 中,MSHTML Editing Platform(即可以通过设置来允许用户实时编辑、拖动 layout 元素以及调整其尺寸等)的文档中描述了三个和 layout 相关的重要特性:
·如果一个 layout 元素中有内容,内容的排版布局将由它的边界矩形框决定。 ·拥有 layout 的意思基本上就是表示某元素是一个矩形。 ·从内部来说,拥有 layout 意思就是一个元素将自己负责绘制其内部内容。
(Editing Platform)
和 layout 自身相关的内部工作机制直到2005年8月才有相应文档描述,当时由于 The Web Standards Project和微软的特别工作小组的原因,Markus Mielke [MSFT] 打开了深入讨论的大门:
一般来说,在 Internet Explorer 的 DHTML 引擎中,元素是不对自己的位置安排负责的。虽然一个 div 或者一个 p 元素都在源码中有一个位置,在文档流有一个位置,但是它们的内容却是由它们最近的一个 layout 祖先(经常是 body)控制安排的。这些元素依赖它们祖先的 layout 来为他们处理诸如决定大小尺寸和测量信息等诸多繁重的工作。
(HasLayout概述)
出处:web.Frontend
责任编辑:moby
上一页 On having layout [1] 下一页 On having layout [3]
◎进入论坛网站综合、网页制作版块参加讨论
|