Zoltán Tamási Zoltán Tamási - 4 months ago 10
HTML Question

Fixed table columns implementation

I moved this question here from Code Review as it was found off-topic there

I'm trying to implement fixed table columns. I've found a quite easy pure CSS implementation, which I haven't seen before. Here you can check out the little fiddle which fixes the first column. I've tested it only in latest IE and Chrome yet.

As I'm not an expert when it comes to deep browser rendering and browser compatibility, I have two main questions:


  1. Why is it actually working? Sounds weird but I really don't understand. According to my best knowledge, using
    absolute
    positioning should not fix it relatively to the scrolling parent, but relatively to it's offset parent, which is the
    tr
    element. So actually I was surprised that it works.

  2. Is it safe? Should it work in different and probably older browsers too? It sounds too good to be true.



Besides I would like to hear your thoughts and tips on this one and other possible solutions. What I would like to avoid is to split the
table
into two and use overlapping to mimic fixed columns (like for example many datatable libraries do).

UPDATE

Interestingly it seems like the
relative
positioning is not even needed on the
tr
elements to work properly. Now I'm completely confused about why and how it's working.

Answer

TR and position: relative

Absolute positioned elements are taken out of the flow. By giving the tbody a padding, some space is created to show the first column in.

It works, because the width of the first column and that padding are fixed (to 150px).

Then there is this weird rule:

table > tbody > tr {
  position: relative;
}

Let's call it Rule R from now on. ;-)

Your remark about the offset parent, which is the tr, sounds about right. However, according to the specs, the behaviour of position: relative on table rows is 'undefined', so that might be a problem.

In Chrome it looks like the whole rule is ignored, and if I remove Rule R, the fiddle still works the same.

So that 'explains' why it works. Rule R would break it, but it doesn't because it is simply ignored (by Chrome at least).

Why the top works

Since there are no positioned elements, the cells responds to the document body, and that explains why it doesn't move with the div's contents.

The absolute positioning would leave the element at its original (static) position, also according to standards. Through CSS (only) the left is changed to 0.

So, the element is positioned on the left side of the body (looking 'fixed') at the top it would have had, if it had been in the flow, so that's its normal top position within the tr. No weirdness there.

FWIW, see updated fiddle that has some content, showing that the entire div contents are moving, but not the first column, nor the contents of the body outside of .container.

Risk

So is there is risk? I think theoretically not, although this is one of those weird implementation that could just trigger some edge case bug in some browsers. It seems to work fine, and if you remove Rule R is seems to follow standards too.

Additional remarks You don't need to specify any width for the table. You could simply let it asjust to the width it needs. The only thing that needs to have a fixed width is the first column. So, a bit stripped down, here is your fiddle.

Comments