您好,欢迎访问一九零五行业门户网

CSS魔法堂:hasLayout原来是这样!

前言过去一直听说旧版本ie下很多诡异bug均由一个神秘角色引起的,那就是haslayout。趁着最近突然发神经打算好好学习css,顺便解答多年来的疑惑。
haslayout到底是何方神圣?haslayout可以简单看作是ie5.5/6/7中的bfc(block formatting context)。也就是一个元素要么自己对自身内容进行组织和尺寸计算(即可通过width/height来设置自身的宽高),要么由其containing block来组织和尺寸计算。而ifc(即没有拥有布局)而言,则是元素无法对自身内容进行组织和尺寸计算,而是由自身内容来决定其尺寸(即仅能通过line-height设置内容行距,通过行距来支撑元素的高度;也无法通过width设置元素宽度,仅能由内容来决定而已)
当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的元素
<html>, <body><table>, <tr>, <th>, <td><img>,<hr><input>, <button>, <select>, <textarea>, <fieldset>, <legend><iframe>, <embed>, <object>, <applet>,<marquee>
触发haslayout==true的方式display: inline-block height: (除 auto 外任何值) width: (除 auto 外任何值) float: (left 或 right) position: absolute writing-mode: tb-rl zoom: (除 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/fixed float:left/right display:inline-block/table-cell/table-caption/flex/inline-flex overflow:(除visible外任意值)
可以看到导致产生新bfc的方式和触发haslayout==true的方式不完全重叠。因此haslayout==true所引发的问题,很大程度可以理解为在不应该的或没有预料到的地方产生新的bfc导致的。
如何兼容?仅当一个元素即在 ie 早期版本中触发了 haslayout,又在其他浏览器中创建了 block formatting context 时,才能避免上述问题的发生。即同时启用上述两者以保证各浏览器的兼容,或者相反,两者皆不启用。
使元素即生成了 block formatting context,又触发了 haslayout
1.1 对于触发 haslayout 的元素,通过 css 设置,使它产生 block formatting context;
1.2 生成 block formatting context 但是没有触发 haslayout 的元素,通过设置 'zoom:1',使其触发 haslayout。
使元素即没有触发 haslayout,又没有创建 block formatting context。
总结虽然我现在已经不用再适配ie5.5/6/7了,但理解haslayout还是很有必要的。其实可以理解为从另一个角度学习bfc吧!
尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/5291166.html肥仔john^_^
感谢谈谈bfc与ie特有属性haslayout
rm8002: 不能同时在 ie6 ie7 ie8(q) 中触发 haslayout 并在其他浏览器中创建 block formatting context 的元素在各浏览器中的表现会有差异
以上就是css魔法堂:haslayout原来是这样! 的详细内容。
其它类似信息

推荐信息