打印

RM8024: 各浏览器对除 TABLE 之外的表格类元素以及它们相对于 CSS 中 display 特性值的相对定位特性的支持存在差异

作者:陆远

标准参考

根据 CSS2.1 规范中的描述,被设定了 'position' 特性值为 'relative' 的框的位置会根据其在普通流 (normal flow) 的位置进行计算。然后此框会相对于 (relative) 它在普通流中的位置进行偏移。如果一个框 B 是相对定位的,则其随后的框的定位计算并不考虑 B 的偏移。
'position:relative' 作用在 table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, and table-caption 这些类型元素上的效果并未定义。

CSS 中的表格模型基于 HTML4 的表格模型,包括了表格,标题,行,行组,列,列组以及单元格。下列 'display' 特性的值可以将表格语义指派给一个任意的元素:

'display' 特性的值 对应 HTML 中的元素
table-row TR
table-row-group TBODY
table-header-group THEAD
table-footer-group TFOOT
table-column COL
table-column-group COLGROUP
table-cell TD, TH
table-caption CAPTION

关于 'position' 特性 及 相对定位 的更多资料,请参考 CSS2.1 规范 9.3.1 Choosing a positioning scheme: 'position' property9.4.3 Relative positioning 中的内容。

关于 CSS 表格模型 特性的更多信息,请参考 CSS2.1 规范 17.2 The CSS table model 中的内容。

问题描述

在 IE6 IE7 IE8(Q) 中,TD/TH 及 TD 元素对设定 'position:relative' 特性及偏移有效,其他均无效;
在 IE8(S) 中,TD/TH 及 CAPTION 元素及它们相对于 CSS 中 display 特性值对设定 'position:relative' 特性及偏移有效,其他均无效;
在 Firefox 中,除 TABLE 之外的所有表格类元素以及它们相对于 CSS 中 display 特性值对设定 'position:relative' 特性及偏移均无效
在 Chrome Safari 中,CAPTION 元素及它相对于 CSS 中 display 特性值 'caption' 对设定 'position:relative' 特性及偏移有效,其他均无效;
在 Opera 中,COL、COLGROUP 元素以及它们相对于 CSS 中 display 特性值对设定 'position:relative' 特性及偏移无效,其他均有效。

造成的影响

此问题可能导致设定了相对定位的符合问题描述的元素的位置在不同浏览器中产生差异,从而影响布局甚至功能实现。

受影响的浏览器

所有浏览器  

问题分析

CSS2.1 规范中直接说明了 'position:relative' 作用在 table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, and table-caption 这些类型元素上的效果并未定义。
下面就对 HTML 中除 TABLE 之外的表格类元素 (包括 TD/TH、TR、THEAD、TBODY、TFOOT、COL、COLGROUP、CAPTION) 以及它们相对于 CSS 中 'display' 特性值 (包括 'table-cell'、'table-row'、'table-header-group'、'table-row-group'、'table-footer-group'、'table-column'、'table-column-group'、'table-caption') 对 'position:relative' 的效果进行分析。

1. 为 TD 元素设定 'position:relative'

分析以下代码:cell_relative.html

<!DOCTYPE html>
<html>
<head>
<style>
  * { margin:0; font:20px/1.5 'Trebuchet MS'; }
  table { border:5px solid black; background:khaki; }
  td { border:2px solid navy; background:mistyrose; }
</style>
</head>
<body>
<table cellpadding="2" cellspacing="5">
  <tr>
    <td>static</td>
    <td>static</td>
    <td>static</td>
  </tr>
  <tr>
    <td>static</td>
    <td style="position:relative; left:30px; top:30px; background:lightskyblue;">relative</td>
    <td>static</td>
  </tr>
  <tr>
    <td>static</td>
    <td>static</td>
    <td>static</td>
  </tr>
</table>
</body>
</html>

上面代码为中间的 TD 元素设置了 position:relative 以及其偏移。

在各浏览器中效果如下:

IE6 IE7 IE8 Opera Firefox Chrome Safari

可见,IE6 IE7 IE8 Opera 中为 TD 元素设定 position:relative 有效。


2. 为 TR 元素设定 'position:relative'

分析以下代码:row_relative.html

<!DOCTYPE html>
<html>
<head>
<style>
  * { margin:0; font:20px/1.5 'Trebuchet MS'; }
  table { border:5px solid black; background:khaki; }
  td { border:2px solid navy; background:mistyrose; }
</style>
</head>
<body>
<table cellpadding="2" cellspacing="5">
  <tr>
    <td>static</td>
    <td>static</td>
  </tr>
  <tr style="position:relative left:30px; top:30px;">
    <td style="background:lightskyblue;">relative</td>
    <td style="background:lightskyblue;">relative</td>
  </tr>
  <tr>
    <td>static</td>
    <td>static</td>
  </tr>
</table>
</body>
</html>

上面代码为中间的 TR 元素设置了 position:relative 以及其偏移。

在各浏览器中效果如下:

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

可见,IE6 IE7 IE8(Q) Opera 中为 TR 元素设定 position:relative 有效。


3. 为其他表格类元素 COL、COLGROUP、THEAD、TBODY、TFOOT、CAPTION 设定 'position:relative'

分析以下代码:other_relative.html

<!DOCTYPE html>
<html>
<head>
<style>
  * { margin:0; font:20px/1.5 'Trebuchet MS'; }
  table { border:5px solid black; background:khaki; }
  td { border:2px solid navy; background:mistyrose; }
</style>
</head>
<body>
COL
<table cellpadding="2" cellspacing="5">
  <col style="position:relative left:200px;" />
  <tr>
    <td>COL</td>
    <td>COL</td>
  </tr>
</table>
<br />
COLGROUP
<table cellpadding="2" cellspacing="5">
  <colgroup style="position:relative left:200px;">
    <col />
  </colgroup>
  <tr>
    <td>COLGROUP</td>
    <td>COLGROUP</td>
  </tr>
</table>
<br />
THEAD, TBODY, TFOOT
<table cellpadding="2" cellspacing="5">
  <thead style="position:relative left:100px;">
    <tr>
      <td>THEAD</td>
    </tr>
  </thead>
  <tbody style="position:relative left:120px;">
    <tr>
      <td>TBODY</td>
    </tr>
  </tbody>
  <tfoot style="position:relative left:140px;">
    <tr>
      <td>TFOOT</td>
    </tr>
  </tfoot>
</table>
<br />
CAPTION
<table cellpadding="2" cellspacing="5">
  <caption style="position:relative left:100px; background:lightskyblue;">CAPTION</caption>
  <tr>
    <td>table cell</td>
  </tr>
</table>
</body>
</html>

上面代码为 COL、COLGROUP、THEAD、TBODY、TFOOT、CAPTION 元素设置了 position:relative 以及其偏移。

在各浏览器中效果如下:

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

可见,所有浏览器均不支持 COL 与 COLGROUP 元素的 position:relative
IE6 IE7 IE8(Q) Firefox 对 THEAD、TBODY、TFOOT、CAPTION 元素设定 position:relative 均无效。
IE8(S) Chrome Safari 对 THEAD、TBODY、TFOOT 元素设定 position:relative 无效,对 CAPTION 元素有效。
Opera 对 THEAD、TBODY、TFOOT、CAPTION 元素设定 position:relative 均有效。


4. CSS 中 'display' 特性值为 'table-cell'、'table-row'、'table-header-group'、'table-row-group'、'table-footer-group'、'table-column'、'table-column-group'、'table-caption' 的元素设定 'position:relative'

上面测试的均为 HTML 中原生为表格类的元素,下面将分析通过设定 'display' 特性1来模拟表格特性的元素对 'position:relative' 是否有效。

注 1: 由于 IE6 IE7 IE8(Q) 不支持上述 'display' 特性值,故下面将只考虑 IE8(S) 及其他非 IE 浏览器。

分析以下代码:dis_relative.html

<!DOCTYPE html>
<html>
<head>
<style>
  * { margin:0; padding:0; font:12px/1 'Trebuchet MS'; }
  h1 { font-weight:bold; border-top:2px solid gray; }
  .table { display:table; border-spacing:5px; border:5px solid black; background:khaki; }
  .tr { display:table-row; }
  .td { display:table-cell; border:2px solid navy; background:mistyrose; padding:2px; }
  .thead { display:table-header-group; }
  .tbody { display:table-row-group; }
  .tfoot { display:table-footer-group; }
  .caption { display:table-caption; }
  .col { display:table-column; }
  .colgroup { display:table-column-group; }
</style>
</head>
<body>
<div class="table">
  <div class="tr">
    <div class="td">table-cell</div>
    <div class="td">table-cell</div>
  </div>
  <div class="tr">
    <div class="td" style="position:relative; left:30px; top:20px; background:lightskyblue;">table-cell</div>
    <div class="td">table-cell</div>
  </div>
  <div class="tr">
    <div class="td">table-cell</div>
    <div class="td">table-cell</div>
  </div>
</div>
<br />
<div class="table">
  <div class="tr">
    <div class="td">table-row</div>
    <div class="td">table-row</div>
  </div>
  <div class="tr" style="position:relative; left:30px; top:20px;">
    <div class="td" style="background:lightskyblue;">table-row</div>
    <div class="td" style="background:lightskyblue;">table-row</div>
  </div>
  <div class="tr">
    <div class="td">table-row</div>
    <div class="td">table-row</div>
  </div>
</div>
<br />
<div class="table">
  <div class="thead" style="position:relative; left:80px; top:20px;">
    <div class="tr">
      <div class="td" style="background:lightskyblue;">table-header-group</div>
    </div>
  </div>
</div>
<br />
<div class="table">
  <div class="tbody" style="position:relative; left:80px; top:20px;">
    <div class="tr">
      <div class="td" style="background:lightskyblue;">table-row-group</div>
    </div>
  </div>
</div>
<br />
<div class="table">
  <div class="tfoot" style="position:relative; left:80px; top:20px;">
    <div class="tr">
      <div class="td" style="background:lightskyblue;">table-footer-group</div>
    </div>
  </div>
</div>
<br />
<div class="table">
  <div class="caption" style="position:relative; left:80px; top:20px; background:lightskyblue;">table-caption</div>
  <div class="tr">
    <div class="td">table-caption</div>
  </div>
</div>
<br />
<div class="table">
  <div class="col" style="position:relative; left:200px;"></div>
  <div class="tr">
    <div class="td">table-column</div>
    <div class="td">table-column</div>
  </div>
</div>
<br />
<div class="table">
  <div class="colgroup" style="position:relative; left:200px;">
    <div class="col"></div>
  </div>
  <div class="tr">
    <div class="td">table-column-group</div>
    <div class="td">table-column-group</div>
  </div>
</div>
</body>
</html>

上面代码上面代码中为 'display' 特性值为 'table-cell'、'table-row'、'table-header-group'、'table-row-group'、'table-footer-group'、'table-column'、'table-column-group'、'table-caption' 的 DIV 元素设置了 position:relative 以及其偏移。

在各浏览器中效果如下:

IE8(S) Chrome Safari Firefox Opera

可见,CSS 中 'display' 特性值为 'table-cell'、'table-row'、'table-header-group'、'table-row-group'、'table-footer-group'、'table-column'、'table-column-group'、'table-caption' 的元素设定 'position:relative' 与对应的表格类元素设定 'position:relative' 的情况一致。


5. 小结

下面通过表格总结各浏览器对除 TABLE 之外的表格类元素以及它们相对于 CSS 中 'display' 特性值设置相对定位 (position:relative) 特性的支持差异:

  IE6 IE7 IE8(Q) IE8(S) Chrome Safari Firefox Opera
TD/TH (display:table-cell) 有效 有效 无效 无效 有效
TR (display:table-row) 有效 无效 无效 无效 有效
THEAD (display:table-header-group) 无效 无效 无效 无效 有效
TBODY (display:table-row-group) 无效 无效 无效 无效 有效
TFOOT (display:table-footer-group) 无效 无效 无效 无效 有效
CAPTION (display:table-caption) 无效 有效 有效 无效 有效
COL (display:table-column) 无效 无效 无效 无效 无效
COLGROUP (display:table-column-group) 无效 无效 无效 无效 无效

解决方案

由于除 TABLE 之外的表格类元素以及它们相对于 CSS 中 display 特性值设定了相对定位后的效果 CSS2.1 规范中没有明确定义,而各浏览器的实现又存在很大差异。所以应避免为这些元素设定 'position:relative'。
若需要实现如冻结表格行或列的效果,可以考虑使用绝对定位其他 TABLE 元素的方式模拟。

参见

知识库

相关问题

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.6。10
Chrome 8.0.552.0 dev
Safari 5.0.2
Opera 10.63
测试页面: cell_relative.html
row_relative.html
other_relative.html
dis_relative.html
本文更新时间: 2010-10-15

关键字

position relative 相对 定位 display table row cell td