zoukankan      html  css  js  c++  java
  • 那些年,我们被耍过的bug——haslayout

    你被IE的bug耍过几次了?

    IE,这个令所有网站设计人员讨厌,但又不得不为它工作的浏览器。不论是6、7还是8,它们都有一个共同的渲染标准haslayout,所以haslayout 是一个非常有必要彻底弄清除的概念。大多 数IE下的显示错误,就是源于它。

    什么是Layout呢?

    "Layout" 是IE特有的一个属性,并不是W3C标准,很多的ie下的css bug都与其息息相关。它决定了一个对象(就是一个标签div、li等)在内容中如何显示、与周围对象的位置关系、以及怎样响应程序或用户产生的事件。

    这个属性可以被一些css强制激活。一些HTML标签默认具有haslayout。
    PS:一个对象的layout属性被激活,它的具体表现就是haslayout=true。我们可以用IE Developer Toolbar工具看到被激活的对象带有"haslayout = -1"的属性。

    特别注意的是,hasLayout 在 IE 8 及之后的 IE 版本中已经被抛弃,所以在实际开发中只需针对 IE 8 以下的浏览器为某些元素触发 hasLayout 。

    一个元素触发 hasLayout 会影响一个元素的尺寸和定位,这样会消耗更多的系统资源,因此 IE 设计者默认只为一部分的元素触发 hasLayout (即默认有部分元素会触发 hasLayout ,这与 BFC 基本完全由开发者通过特定 CSS 触发并不一样),这部分元素如下:

    • <html>, <body>
      <table>, <tr>, <th>, <td>
      <img>
      <hr>
      <input>, <button>, <select>, <textarea>, <fieldset>, <legend>
      <iframe>, <embed>, <object>, <applet>
      <marquee>

     很多情况下,我们把 hasLayout的状态改成true 就可以解决很大部分ie下显示的bug。 
    hasLayout属性不能直接设定,你只能通过设定一些特定的css属性来触发并改变 hasLayout 状态。下面列出可以触发hasLayout的一些CSS属性值。 

    ------------------------------------- 
    display 
    启动haslayout的值:inline-block 
    取消hasLayout的值:其他值 
    -------------------------------------- 
    width/height 
    启动hasLayout的值:除了auto以外的值 
    取消hasLayout的值:auto 
    --------------------------------------- 
    position 
    启动hasLayout的值:absolute 
    取消hasLayout的值:static 
    ---------------------------------------- 
    float 
    启动hasLayout的值:left或right 
    取消hasLayout的值:none 
    --------------------------------------- 
    zoom 
    启动hasLayout的值:有值 
    取消hasLayout的值:narmal或者空值 
    (zoom是微软IE专有属性,可以触发hasLayout但不会影响页面的显示效果。zoom: 1常用来除错,不过 ie 5 对这个属性不支持。) 
    ---------------------------------------- 
    writing-mode: tb-rl 
    这也是微软专有的属性。 
    ie7还有一些额外的属性可以触发该属性(不完全列表): 
    min-height: (任何值) 
    max-height: (任何值除了none) 
    min- (任何值) 
    max- (任何值除了none) 
    overflow: (任何值除了visible) 
    overflow-x: (任何值除了visible) 
    overflow-y: (任何值除了visible)5 
    position: fixed 

    重置haslayout

    在没有其它属性激活layout的情况下,使用下面的css可以重置haslayout属性:

    • width, height (设为 "auto")
    • max-width, max-height (设为 "none")(在 IE 7 中)
    • position (设为 "static")
    • float (设为 "none")
    • overflow (设为 "visible") (在 IE 7 中)
    • zoom (设为 "normal")
    • writing-mode (从 "tb-rl" 设为 "lr-t")

    display 属性的不同:当用"inline-block"激活了haslayout 属性时,就算在一条独立的规则中覆盖这个属性为"block"或"inline",haslayout 这个标志位也不会被重置为 false。

    把 mid-width, mid-height 设为它们的默认值"0"仍然会赋予 hasLayout,但是 IE 7 却可以接受一个不合法的属性"auto"来重置 hasLayout。

    haslayout 问题引起的常见 bug

    IE6 及更低版本的双空白边浮动 bug

    bug 修复: display:inline;

    IE5-6/win 的 3 像素偏移 bug

    bug 修复: _height:1%;

    IE6 的躲躲猫(peek-a-boo) bug

    bug 修复: _height:1%;

    这里列出触发 hasLayout 元素的一些效果

    1.阻止外边距折叠

    两个相连的 div 在垂直上的外边距会发生叠加,而触发 hasLayout 的元素之间则不会有这种情况发生,如下图:

    也可以查看 Demo 。

    上图的例子中,三个 div 各包含一个 p 元素,三个 div 及其包含的 p 元素都有顶部和底部的外边距,但只有第三个 div 的边距没有与它的子元素 p 的外边距折叠。这是因为第三个 div 使用 zoom: 1 触发了 hasLayout ,阻止了它与它的子元素的外边距折叠。

    另外,例子中也使用了 overflow: hidden 触发元素的 BFC ,这利用了 BFC 阻止外边距折叠的特性达到元素在 IE 与现代浏览器下的表现统一。

    2.可以包含浮动的子元素,即计算高度时包括其浮动子元素

    效果如图:

    上图的例子中,有两个 div ,它们各包含一个设置了浮动的 p 元素,但第一个 div 实际被浏览器判断为没有高度和宽度,即高度为 0 ,上下边框重叠在一起。而第二个 div 使用 zoom: 1 触发了 hasLayout ,可以包含浮动元素,因此能正确表现出高度,其边框位置也正常了。

    本例子中也使用了 overflow: hidden 触发 BFC ,跟上例相似,这利用了 BFC 可以包含浮动子元素的特性达到元素在 IE 与现代浏览器下的表现统一。

    3.背景图像显示问题

    元素背景图不能正确显示是网页重构中最常见的问题之一了,在 IE 7 及以下的 IE 版本中,没有设置高度、宽度的元素往往不能显示出背景图(背景色则显示正常),这实际上与 hasLayout 有关。实际的情况是,没有触发 hasLayout 的元素不能显示背景图,上面有说过,触发 hasLayout 也就是使到元素拥有布局,换句话说,拥有布局的元素才能正确显示背景图。如下图:

    也可以看 Demo (在 IE 7 或更低版本的 IE 下查看以观察背景图问题)。

    上图两个 div 都设置了背景图,但只有使用 zoom: 1 触发了 hasLayout 的第二个 div 才能正确显示背景图。

    本例子中没有触发元素的 BFC ,这是因为在现代浏览器中,元素本身并没有背景图显示问题。

    可以看出,上面的第一、二个例子中,为了使到元素在 IE (包括低版本 IE 以及较新版本的 IE)和现代浏览器中表现尽量统一同时触发了 hasLayout 和 BFC ,而第三个例子中的问题因为只在低版本 IE 中出现,所以只需为低版本 IE 触发 hasLayout ,这些技巧在实际项目中需要特别注意。

    上面也有说道,hasLayout 与很多 IE 下的显示 bugs 都有关,实际上很多莫名奇妙的 bugs 都因 hasLayout 而起,因此只要适当的触发元素的 hasLayout ,很多 IE bugs 往往就能解决。

  • 相关阅读:
    简单明了的带你理解springboot原理和三大核心注解
    Spring Boot(一):入门篇
    【Mysql优化】聚簇索引与非聚簇索引概念
    Mysql索引原理与优化
    Mysql全文索引的使用
    索引的优缺点,如何创建索引
    184 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 04 例:字符串与byte(即:字节)数组间的相互转换
    183 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 03 String常用方法(下)
    182 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 02 String常用方法(上)
    181 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 01 String常用方法简介
  • 原文地址:https://www.cnblogs.com/chaoran/p/4789898.html
Copyright © 2011-2022 走看看