大多数浏览器存在的缺陷:忽略'tbody'、 'tr'和'td'上的相对定位?

16
当您尝试将元素绝对定位到 tbodytr 甚至 td 上时,您会发现在大多数浏览器中这是不起作用的。 它在 Firefox 中按预期工作,但在 IE、Edge 和 Chrome 中不起作用。 tbodytr 甚至 td 上的 position: relative 被忽略。 然后,第一个具有 position: relative 的父级被用作绝对定位的“锚点”。
顺便说一下:当您将 tbody 设置为 display: block 时,position: relative 确实起作用。但是那时您可能会在表行的宽度上遇到麻烦。一般来说,子元素不再像表格元素一样精确地行为。列会消失……但这不是问题的一部分。
我的问题是: 为什么在 tbodytrtd 上忽略了 position: relative? 是否有任何原因造成这种行为? 这应该是需要修复的错误吗?

.example {
  border: 1px solid #ccc;
  position: relative;
  background: #eee;
  margin: 2em;
  padding: 2em;
  width: 50%;
}

.abs {
  display: block;
  position: absolute;
  left: 100%;
  top: 0;
}

table {
  //border: 5px solid rgba(255,200,0,0.2);
  border-collapse: collapse;
}

tbody {
  border: 2px solid red;
  position: relative;
}

td {
  border: 1px solid lime;
  padding: 1em;
}

.text--red {
  color: red;
}

.text--gray {
  color: gray;
}
<ul>
  <li class="text--gray">Gray background is table wrapper with position relative.</li>
  <li class="text--red">Redline is tbody with position relative.</li>
</ul>

<div class="example">
  <table>
    <tbody>
      <tr>
        <td>tbody1>tr1>td</td>
      </tr>
      <tr>
        <td>tbody1>tr2>td</td>
      </tr>
      <tr class="abs abs--1">
        <td>tbody1>tr3>td absolute position to tbody</td>
      </tr>
    </tbody>
    <tbody>
      <tr>
        <td>tbody2>tr1>td</td>
      </tr>
    </tbody>
    <tbody>
      <tr>
        <td>tbody3>tr1>td</td>
      </tr>
      <tr class="abs abs--2">
        <td>tbody3>tr2>td absolute position to tbody</td>
      </tr>
    </tbody>
  </table>
</div>

来源:

https://www.w3.org/TR/css-position-3/#valdef-position-relative

https://www.w3.org/TR/css-position-3/#property-index

属性名:position 适用于:除了 table-column-grouptable-column 以外的所有元素。

https://developer.mozilla.org/en-US/docs/Web/CSS/position#relative 关于“堆叠上下文”的内容,但这不是本问题的主题。

当 z-index 的值不为 auto 时,此值 (position: relative) 会创建一个新的堆叠上下文。它对于 table-*-grouptable-rowtable-columntable-celltable-caption 元素的影响未定义。

相关问题:

  1. 如何在 tbody 上方添加覆盖层?
  2. 如何相对于表格单元格进行定位?

因为那是规范吗? - Paulie_D
@Paulie_D - 这是指 Firefox 的规格还是 Chrome/Edge 的行为? - Alohci
我刚刚发现trtd也是一样的。因此,例如您无法将绝对定位的子DIV放置在其父TD中。因此,我编辑了我的问题,并将其扩展到trtd - Matěj Kříž
@Paulie_D - 规范:属性position适用于所有元素,除了table-column-grouptable-column。请参见:https://www.w3.org/TR/css-position-3/#property-index - Matěj Kříž
不幸的是,在Bootstrap streteched-link中也无法工作:https://codesandbox.io/s/xenodochial-bas-t1zoi - pom421
1个回答

9
MDN所说的在CSS2中是准确的。多年来,position: relative对内部表格框的影响是未定义的(§9.3.1),并且实现远非互操作。
这仅在最近的css-position-3中发生了变化,现在定义如下效果:

position: relative对表格元素的影响如下:

  • table-row-group、table-header-group、table-footer-group和table-row相对于其在表格中的正常位置进行偏移。如果表格单元格跨越多行,则仅偏移源自相对定位行的单元格。

  • table-column-group、table-column不会偏移各自的列,并且在应用position: relative时没有视觉效果。

  • table-caption和table-cell相对于其在表格中的正常位置进行偏移。如果表格单元格跨越多个列或行,则整个跨度的单元格将被偏移。

然而,实现仍然存在各种问题,这是因为CSS表格模型的实现仍然混乱,不可预测,不完全互操作,并且充满了历史包袱,没有人愿意去碰它。通过浏览css-tables-3 specthe CSSWG's GitHub issues for that spec可以看出来。
话虽如此,浏览器供应商正在缓慢而谨慎地解决一些类似位置的内部表格框的问题,逐步加以改进。只是不要期望有快速进展。
顺便说一下:position: relative在将tbody设置为display: block时有效。
是的,因为这样做tbody就不再像tbody一样运作,而是开始像div一样运作,并且您会完全破坏表格的CSS结构。

1
Chromium的错误报告在https://bugs.chromium.org/p/chromium/issues/detail?id=417223。 - thelem
1
在链接的页面上,我现在读到: “如果在表行组、表头组、表尾组或表行框上指定了偏移量,则该偏移量会影响框中的所有内容,包括源自受影响行的所有表格单元格,但不包括那些没有受影响的单元格。注意:由于位置不适用于表列组或表列框,因此它们不受相对定位的影响。”此外,有两个不同的问题——相对元素本身的定位和其绝对定位的子元素的定位。偏移量可能不会影响“tr”,但它仍然可能是子元素的参考。 - Jānis Elmeris
1
@Jānis Elmeris:是的,他们一直在努力。WD在去年进行了更新。我似乎模糊地记得一些实现也进行了更新,但我没有所有的细节。 - BoltClock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接