前言 过去一直听说旧版本ie下很多诡异bug均由一个神秘角色引起的,那就是haslayout。趁着最近突然发神经打算好好学习css,顺便解答多年来的疑惑。
haslayout到底是何方神圣?
haslayout可以简单看作是ie5.5/6/7中的bfc(block formatting context)。也就是用于决定一个元素要么自己对自身内容进行组织和尺寸计算,要么由其containing block来组织和尺寸计算。
当haslayout为true时(就是所谓的拥有布局),相当于元素产生新bfc,元素自己对自身内容进行组织和尺寸计算;
当haslayout为false时(就是所谓的不拥有布局),相当于元素不产生新bfc,元素由其所属的containing block进行组织和尺寸计算。
和产生新bfc的特性一样,haslayout无法通过css属性直接设置,而是通过某些css属性间接开启这一特性。不同的是某些css属性是以不可逆方式间接开启haslayout为true。并且默认产生新bfc的只有 html元素,而默认haslayout为true的元素就不只有 html元素了。
另外我们可以通过 object.currentstyle.haslayout属性来判断元素是否开启了haslayout特性。
到这里我们应该了解到若要理解haslayout则必须理解bfc,因此这里可参考 css魔法堂:重新认识box model、ifc、bfc和collapsing margins
默认 haslayout==true的元素 , , , , ,, , , , , , , , ,
触发 haslayout==true的方式 display: inline-blockheight: (除 auto 外任何值)width: (除 auto 外任何值)float: (left 或 right)position: absolutewriting-mode: tb-rlzoom: (除 normal 外任意值)
ie7 还有一些额外的属性(不完全列表)可以触发 haslayout :
min-height: (任意值)min-width: (任意值)max-height: (除 none 外任意值)max-width: (除 none 外任意值)overflow: (除 visible 外任意值,仅用于块级元素)overflow-x: (除 visible 外任意值,仅用于块级元素)overflow-y: (除 visible 外任意值,仅用于块级元素)position: fixed
ie6 以前的版本(也包括 ie6 及以后所有版本的混杂模式,其实这种混杂模式在渲染方面就相当于 ie 5.5), 通过设置任何元素的 'width' 或 'height'(非auto)都可以触发 haslayout ; 但在 ie6 和 ie7 的标准模式中的行内元素上却不行,设置 'display:inline-block' 才可以。
其中通过 display:inline-block或 min-width:0或 min-height:0将不可逆地启用haslayout特性。而在没有其他属性启用haslayout时,可通过以下方式关闭haslayout
max-width, max-height (设为 none)(在ie7中)position (设为 static)float (设为 none)overflow (设为 visible) (在ie7中)zoom (设为 normal)writing-mode (从 tb-rl 设为 lr-t)
而产生新bfc的css属性
position:absolute/fixedfloat:left/rightdisplay:inline-block/table-cell/table-caption/flex/inline-flexoverflow:(除visible外任意值)
可以看到导致产生新bfc的方式和触发 haslayout==true的方式不完全重叠。因此haslayout==true所引发的问题,很大程度可以理解为在不应该的或没有预料到的地方产生新的bfc导致的。
如何兼容? 仅当一个元素即在 ie 早期版本中触发了 haslayout,又在其他浏览器中创建了 block formatting context 时,才能避免上述问题的发生。即同时启用上述两者以保证各浏览器的兼容,或者相反,两者皆不启用。
使元素即生成了 block formatting context,又触发了 haslayout对于触发 haslayout 的元素,通过 css 设置,使它产生 block formatting context;
生成 block formatting context 但是没有触发 haslayout 的元素,通过设置 'zoom:1',使其触发 haslayout。
使元素即没有触发 haslayout,又没有创建 block formatting context。
总结 虽然我现在已经不用再适配ie5.5/6/7了,但理解haslayout还是很有必要的。其实可以理解为从另一个角度学习bfc吧!尊重原创,转载请注明来自:肥仔john^_^
感谢