打印

RX8004: 非 IE 浏览器中 'margin' 特性对 TABLE 元素的 align 属性会有影响

作者:陆远

标准参考

根据 HTML4.01 规范中的描述,TABLE 元素的 align 属性,这个属性可以取 'left'、'center'、'right' 三个值。它指定了 TABLE 元素在文档中的位置,三个属性值分别对应 '居左'、'居中'、'居右',描述的是 TABLE 元素自身相对于其父容器的对齐方式。
同时,align 属性已被废弃。不赞成使用。

关于 TABLE 元素的 align 属性 的详细信息,请参考 HTML4.01 规范 11.2.1 The TABLE element 中的内容。

问题描述

在 IE6 IE7 IE8 中,CSS 的 'margin' 特性不会影响 TABLE 元素的 align="center" 设定的居中对齐效果;
在其他浏览器中,TABLE 元素的 align="center" 被理解为 margin-left:auto | margin-right:auto,单独定义的 'margin' 特性将覆盖由 TABLE 元素的 align 属性转换生成的 'margin' 特性的值,从而使 TABLE 元素失去原有的居中效果。

造成的影响

不合理地为 TABLE 元素同时使用 align="center" 及 'margin' 特性,将使 TABLE 元素在非 IE 浏览器中失去居中效果,从而造成布局差异。

受影响的浏览器

Firefox Chrome Safari Opera  

问题分析

分析以下代码:

<div id="d" style="width:300px; height:50px; background:thistle;">
  <table id="t" cellspacing="0" style="width:200px; border:3px solid black; margin:0 20px;" align="center">
    <tr>
      <td style="background:wheat;">Text Text Text Text Text Text</td>
    </tr>
  </table>
</div>

TABLE 元素【t】的 align 属性为 center,但又设置了 CSS 的 margin:0 20px

这段代码在各浏览器环境内运行效果如下:

IE6 IE7 IE8 Firefox Chrome Safari Opera
IE margin on table non-IE margin on table

可见:

  • IE 中,margin:0 20px 并没有对 align="center" 造成影响,TABLE 元素仍然居中对齐;
  • 其他浏览器 中,margin:0 20px 使原本居中对齐的 TABLE 元素不再居中,而是位于距离其父容器左边界 20px 的位置。

TABLE 元素是块级元素,W3C 规范中指出块级元素的水平居中可利用 'margin-left' 和 'margin-right' 设置值为 'auto' 值来实现,详细请参考 CSS2.1 规范第 10.3.3 Block-level, non-replaced elements in normal flow 节,以及 CSS: Centering Things

通过查看浏览器的开发人员工具可以得到,在 Chrome Safari Opera 中,均将 TABLE 元素的 align="center" 转换为 CSS 的 margin-left:auto 及 margin- right:auto。而显式设置的 'margin' 特性会将浏览器经由 align="center" 转换而来的 'margin' 特性的值覆盖,导致了 TABLE 元素无法居中对齐。


引申阅读

Firefox 虽然无法查看转换后的CSS,但是可以通过其源代码找到转换过程:

Firefox 3.6/content/html/content/src/nsHTMLTableElement.cpp

static void
MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                      nsRuleData* aData)
{
    ...
      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);

      if (value && value->Type() == nsAttrValue::eEnum) {
        if (value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_CENTER ||
            value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_MOZ_CENTER) {
          nsCSSRect& margin = aData->mMarginData->mMargin;
          if (margin.mLeft.GetUnit() == eCSSUnit_Null)
            margin.mLeft.SetAutoValue();
          if (margin.mRight.GetUnit() == eCSSUnit_Null)
            margin.mRight.SetAutoValue();
        }
      }
    ...
}

解决方案

由于 TABLE 元素的 align 属性已经被 W3C 废弃,所以在考虑 TABLE 元素对齐问题上应避免使用 align 属性,而改用 CSS。

  • 使用CSS的 float:left 代替 align="left";
  • 使用CSS的 float:right 代替 align="right";
  • 使用CSS的 margin-left:auto 及 margin-right:auto 代替 align="center"。

参见

知识库

相关问题

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.6.2
Chrome 5.0.356.2 dev
Safari 4.0.5
Opera 10.51
测试页面: margin_on_table.html
本文更新时间: 2010-06-24

关键字

align center margin auto float 居中 对齐 边距 浮动