• IE双边距bug


    标准参考

    根据 W3C CSS2.1 规范中的描述,对于非替换的浮动元素,若 'margin-left' 或 'margin-right' 特性的计算值为 'auto',则它们的实际使用值为 '0'。

    除此之外,'margin-left' 与 'margin-right' 特性的计算则采用其自身定义的规范。

    关于 'margin-left'、'margin-right' 以及 非替换的浮动元素宽度计算 的详细信息,请参考 CSS2.1 规范 8.3 Margin properties: 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', and 'margin' 以及 10.3.5 Floating, non-replaced elements 中的内容。

    问题描述

    在 IE5.0 IE5.5 IE6 中,当为一个块级元素同时设置了向左浮动(float:left)及左边距或右边距('margin-left' | 'margin-right')后,则该元素的左边距或右边距在某些情况下会是设定值的两倍。同样地,向右浮动(float:right)及右边距 ('margin-right')也存在此现象。

    这个是 IE 著名的 "双边距Bug"(IE Double Margin Bug)。

    造成的影响

    这种双倍边距的怪异现象会对页面造成很多影响,如意外折行、溢出、文字重叠等诸多兼容性问题。

    受影响的浏览器

    IE5.0 IE5.5 IE6  

    问题分析

    首先重现这个 Bug。

    分析以下代码:

    <!DOCTYPE html>
    <html>
    <head>
    <script>
      window.onload = function () {
        document.getElementById("d1").innerHTML = document.getElementById("d1").parentNode.offsetWidth;
        document.getElementById("d2").innerHTML = document.getElementById("d2").parentNode.offsetWidth;
      }
    </script>
    </head>
    <body style="font:12px Arial; margin:0;">
    <div style="100px;">
      <div style="background:gold; float:left;">
        <div id="d1" style="float:left; margin:0 50px; background:olive; 100px; height:50px;"></div>
      </div>
      <div style="background:pink; float:left;">
        <div id="d2" style="float:right; margin:0 50px; background:deeppink; 100px; height:50px;"></div>
      </div>
    </div>
    </body>
    </html>

    上面代码中有两组 DIV 容器,容器内的 DIV 元素分别设置了向左浮动(float:left)与向右浮动(float:right),且左右边距均为 50px(margin:0 50px)。当页面加载完毕后将 DIV 容器的 offsetWidth 显示出来。

    在各浏览器中打开这个页面效果如下:

    IE5.0 IE5.5 IE6IE7 IE8 Firefox Chrome Safari Opera
    IE5-6 double margins non IE5-6 double margins

    从上面的例子与截图可见:

    • IE5.0 IE5.5 IE6 中,当一个块级元素向左浮动时,其左边距会出现双倍于设定的边距值的现象。当一个块级元素向右浮动时,其右边距会出现双倍于设定的边距值的现象。由于深黄色的块级元素为其容器内的最后一个左浮动元素,所以其右边距也会出现双倍于设定的右边距值的现象;
    • 其他浏览器 中,没有上述的现象,浏览器遵照 W3C 规范对页面元素进行解释及渲染。

    触发此 Bug 的条件有 3 个:

    1. 若一个元素向左浮动(float:left),且其设置的左边距('margin-left')大于其至容器的左侧内边界的距离:
      该元素实际的左边距 = 设置的左边距 * 2 - 左边界至容器的距离;
    2. 同样地,若一个元素向右浮动(float:right),且其设置的右边距 ('margin-right')大于其至容器的右侧内边界的距离:
      该元素实际的右边距 = 设置的右边距 * 2 - 右边界至容器的距离;
    3. 若一个元素向左浮动(float:left),这个元素为其父容器的最后一个左浮动元素,且其设置的右边距('margin-right')大于其至容器的右侧内边界的距离:
      该元素的实际右边距 = 设置的右边距 * 2。

    下面结合上面的触发条件看一组更加复杂的例子:

    <style>
      .fl { float:left; height:30px; background:gray; }
      #A { 90px; margin:0 10px; }
      #B { 85px; margin-left:150px; }
      #C { 100px; margin-left:100px; }
    </style>
    <div style="600px; height:30px; background:#CCC;">
      <div id="A" class="fl">10 90 10</div>
      <div id="B" class="fl">150 85 0</div>
      <div id="C" class="fl">100 100 0</div>
    </div>

    测试代码中 DIV 容器中包含了三个 DIV 子元素,这三个子元素均为左浮动元素,且均拥有 'margin-left' 特性。

    不同的浏览器运行的结果列表如下:

    IE5.0
    IE5.5
    IE6
    IE5-6 double margins
    IE7
    IE8
    Firefox
    Chrome
    Safari
    Opera
    non IE5-6 double margins

    IE5.0 IE5.5 IE6 中,

    • 【A】的左边距容器的距离为 0,其设置的左边距为 10px,10 > 0。则【A】满足上面的条件1,触发此 Bug。【A】实际的左边距变为 10 * 2 - 0 = 20px。
    • 【B】的左边距容器的距离为 120px(20 + 90 + 10),其设置的左边距为 150px,150 > 120。则【B】满足上面的条件1,触发此 Bug。【B】实际的左边距变为150 * 2 - 120 = 180px。
    • 【C】的左边距容器的距离为 385px(20 + 90 + 10 + 180 + 85),其设置的左边距为 100px,100 < 285。则【C】不满足触发此 Bug 的条件。【C】实际的左边距仍然为 100px。

    上面讨论的都是元素浮动之前为块级元素,下面观察一下 'display' 特性分别为 'inline' 及 'block' 的 SPAN 元素浮动后的情况:

    <div style="100px; height:20px; background:#ccc;">100 x 20</div>
    <span style="float:left; margin-left:100px; 100px; height:20px; background:gray;">inline FLOAT</span>
    <br /><br />
    <div style="100px; height:20px; background:#ccc;">100 x 20</div>
    <span style="float:left; margin-left:100px; 100px; height:20px; background:gray; display:block">block FLOAT</span>

    这段代码在不同浏览器中运行效果为:

    IE5.0
    IE5.5
    IE6
    IE5-6 double margins
    IE7
    IE8
    Firefox
    Chrome
    Safari
    Opera
    non IE5-6 double margins

    从上面一组截图中很明显的看出,双边距 Bug 会作用于 'display' 特性为 'block' 的元素,对于 'inline' 的元素不会触发此 Bug。

    解决方案

    • 尽量避免同时使用 'margin-left' 与 float:left,及 'margin-right' 与 float:right;
    • 由于这个 Bug 对于 'display' 特性为 'inline' 的元素不会触发,所以可以通过设置 display:inline 消除此 Bug,由于此 Bug 仅在元素浮动时发生,而浮动将使该元素 'display' 特性计算为 'block' 或者 'table'(见 CSS2.1 规范第 9.7 Relationships between 'display', 'position', and 'float' 节),因此可以通过设置 display:inline 消除双边距 Bug。

    From;http://w3help.org/zh-cn/causes/RX1001

  • 相关阅读:
    [C/C++ IDE] CLion 配置使用教程
    PyCharm安装使用教程
    SMALI语法大全
    SMALI语法入门教程
    Samba + DLAN 实现电视机播放电脑文件
    深入浅出讲解低功耗蓝牙(BLE)协议栈
    吐血推荐珍藏的Visual Studio Code插件
    为什么我推荐你用 Ubuntu 开发?
    WebBrowser响应页面中的blank开新窗口及window.close关闭本窗体
    C# Task的简单使用
  • 原文地址:https://www.cnblogs.com/autismtune/p/5243314.html
Copyright © 2020-2023  润新知