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 href="https://www.jb51.net/allbrowsers.css" type="text/css" /> <!--[if lte IE 6]> <link href="https://www.jb51.net/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,也只是某种内部的标志位而已。