打印

RB1006: IE6 IE7 IE8(Q) 中触发了 hasLayout 的元素若包含 TEXTAREA 元素及某些 type 的 INPUT 元素,其 'margin-left' 和 'margin-right' 会与预期不符

作者:陆远

标准参考

根据 CSS2.1 规范中的描述,margin 系列特性指定了一个框的 margin area 的宽度,盒模型示意图如下:
Box Model

关于 margin 与 盒模型 的更多信息,请参见 CSS2.1 规范 8.1 Box dimensions8.3 Margin properties 中的内容。

问题描述

IE6 IE7 IE8(Q) 中,若一个触发了 hasLayout 的元素其内第一个非空白节点 (即 children[0]) 为 TEXTAREA 元素 或者 type 属性值为 text、password、submit、reset、button、file 的 INPUT 元素,并且这个元素设定了 'margin-left'、'margin-right' 特性,则 'margin-left'、'margin-right' 特性指定的值会应用于其相应方向的 padding 上。

造成的影响

此问题可能导致设定 'margin-left'、'margin-right' 在 IE6 IE7 IE8(Q) 与其他浏览器中产生差异,从而影响布局。

受影响的浏览器

IE6 IE7 IE8(Q)  

问题分析

对于此问题,我们通过以下的测试用例来说明。

分析以下代码:

<!DOCTYPE html>
<html>
<head>
<style>
  * { margin:0; padding:0; font:12px 'Trebuchet MS'; }
</style>
</head>
<body>
<div style="width:400px; position:relative;">
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <input id="i1" type="text" value="text" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <input id="i2" type="text" value="text" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <input id="i1" type="password" value="password" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <input id="i2" type="password" value="password" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <input id="i1" type="checkbox" value="checkbox" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <input id="i2" type="checkbox" value="checkbox" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <input id="i1" type="radio" value="radio" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <input id="i2" type="radio" value="radio" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <input id="i1" type="submit" value="submit" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <input id="i2" type="submit" value="submit" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <input id="i1" type="image" src="google_small.gif" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <input id="i2" type="image" src="google_small.gif" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <input id="i1" type="reset" value="reset" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <input id="i2" type="reset" value="reset" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <input id="i1" type="button" value="button" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <input id="i2" type="button" value="button" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <input id="i1" type="file" value="file" style="width:100px;" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <input id="i2" type="file" value="file" style="width:100px;" />input
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <img src="google_small.gif" />img
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <img src="google_small.gif" />img
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <button>button</button>button
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <button>button</button>button
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <iframe style="width:100px; height:30px;" src="google_small.gif"></iframe>iframe
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <iframe style="width:100px; height:30px;" src="google_small.gif"></iframe>iframe
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <select style="width:100px; height:30px;"></select>select
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <select style="width:100px; height:30px;"></select>select
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <textarea style="width:100px; height:30px;"></textarea>textarea
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <textarea style="width:100px; height:30px;"></textarea>textarea
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <object type="application/x-shockwave-flash" style="width:100px; height:30px;" data="clock.swf">
        <param name="src" value="clock.swf" />
      </object>object
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <object type="application/x-shockwave-flash" style="width:100px; height:30px;" data="clock.swf">
        <param name="src" value="clock.swf" />
      </object>object
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px;">
      <embed type="application/x-shockwave-flash" style="width:100px; height:30px;" src="clock.swf"></embed>embed
    </div>
  </div>
  <br />
  <div style="background:wheat;">
    <div style="background:plum; zoom:1; margin:0 50px; text-align:right;">
      <embed type="application/x-shockwave-flash" style="width:100px; height:30px;" src="clock.swf"></embed>embed
    </div>
  </div>
  <div style="position:absolute; top:0; left:99px; background:blue; width:2px; height:1500px;"></div>
  <div style="position:absolute; top:0; right:99px; background:blue; width:2px; height:1500px;"></div>
</div>
</body>
</html>

上面代码分为若干组,各组中均按照问题描述中的结构编写代码,区别为触发了 hasLayout 的元素内的第一个非空白节点不同。

这段代码在不同的浏览器环境中的表现如下:

IE6 IE7 IE8(Q) IE8(S) Firefox Opera Safari Chrome

然而根据上面的测试代码的结果可见,

  • IE6 IE7 IE8(Q) 下,触发了 hasLayout 的元素其内第一个非空白节点 (即 children[0]) 为 TEXTAREA 元素 或者 type 属性值为 text、password、submit、reset、button、file 的 INPUT 元素,并且这个元素设定了 'margin-left'、'margin-right' 特性,则 'margin-left'、'margin-right' 特性指定的值会应用于其相应方向的 padding 上。但这块多余的区域并不是 padding。
  • IE8(S) Firefox Chrome Safari Opera 下,浏览器按照 W3C 的规范对代码进行解释,为我们预期的效果。

解决方案

在 INPUT、TEXTAREA 元素之前放一个触发了 hasLayout 的空 SPAN 元素。

例如:

<span style="zoom:1;"></span>

参见

知识库

相关问题

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.6.10
Chrome 7.0.517.17 dev
Safari 5.0.2
Opera 10.62
测试页面: IE67_DM.html
本文更新时间: 2010-09-25

关键字

margin hasLayout input textarea