Bug in most browsers?: Ignoring position relative on 'tbody', 'tr' and 'td'?
Asked Answered
H

1

16

When you try to absolutely position element to tbody, tr and even td you find out it does not work in most browsers. It works as expected in Firefox. Not in IE, Edge and Chrome.

position: relative on tbody, tr and even td is ignored. And then first parent with position: relative is used as "anchor" for absolute placing.

BTW: position: relative do works when you set tbody to display: block. But then you can be in trouble with widths of table rows. Generally, the child elements no more precisely behave as table elements. Columns are gone.. But it is not part of this question.

My questions are:
Why is position: relative ignored on tbody, tr td?
Is there any reason for this behavior?
Is it a bug which should be fixed?

.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>

Sources:

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

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

Property name: position Applies to: all elements except table-column-group and table-column

https://developer.mozilla.org/en-US/docs/Web/CSS/position#relative About 'stacking context' but that is not the subject of this question

This value (position: relative) creates a new stacking context when the value of z-index is not auto. Its effect on table-*-group, table-row, table-column, table-cell, and table-caption elements is undefined.

Related questions:

  1. Overlay on top of tbody
  2. Positioning relative to table-cell
Himalayas answered 14/8, 2018 at 14:12 Comment(5)
Because that's the spec?Lordan
@Lordan - What's the spec? The Firefox behaviour or the Chrome/Edge behaviour ?Cathepsin
I just find out it is the same for tr and td. So you are not able for example make absolutely positioned child DIV to its parent TD. So I edited my question and extend it also to tr and td.Sickroom
@Lordan - Specs: Property position applies to all elements except table-column-group and table-column. See: w3.org/TR/css-position-3/#property-indexSickroom
Unfortunately, it doesn't work either in Bootstrap streteched-link : codesandbox.io/s/xenodochial-bas-t1zoiLuminary
A
9

What MDN says is accurate as of CSS2. For many years the effect of position: relative on internal table boxes was undefined (§9.3.1), and implementations were far from interoperable.

This changed only recently in css-position-3, which now defines the effects as follows:

The effect of position: relative on table elements is defined as follows:

  • table-row-group, table-header-group, table-footer-group and table-row offset relative to its normal position within the table. If table-cells span multiple rows, only the cells originating in the relative positioned row is offset.

  • table-column-group, table-column do not offset the respective column and has no visual affect when position: relative is applied.

  • table-caption and table-cell offset relative to its normal position within the table. If a table cell spans multiple columns or rows the full spanned cell is offset.

However implementations are still all over the place, and the reason for that is because implementations of the CSS table model remain chaotic, unpredictable, not completely interoperable and full of historical baggage that no one wants to touch with a 10-foot pole. You can tell by a skimming through the css-tables-3 spec and the CSSWG's GitHub issues for that spec.

Having said that, browser vendors are slowly and cautiously addressing tangential issues like positioning of internal table boxes like this bit by bit. Just don't expect rapid progress.

BTW: position: relative do works when you set tbody to display: block.

Yes, because by doing so the tbody stops functioning like a tbody and starts acting like a div, and you completely destroy the CSS structure of your table.

Adora answered 3/10, 2018 at 10:44 Comment(3)
Chromium bug report is bugs.chromium.org/p/chromium/issues/detail?id=417223Incorporator
On the linked page I now read: "If specified on a table-row-group, table-header-group, table-footer-group, or table-row box the shift affects all the contents of the box, including all table cells that originate in the affected row, but not those that don’t. Note: Since position does not apply to table-column-group or table-column boxes, they are not affected by relative positioning." Also, there are two different issues – positioning of the relative element itself and of its absolutely positioned children. Offset may not affect "tr", but it may still be reference for the children.Impeach
@Jānis Elmeris: Yeah, they've been working on it. The WD was updated last year. I seem to vaguely recall some implementations being updated as well, but I don't have all the specifics.Adora

© 2022 - 2024 — McMap. All rights reserved.