170

When I try to use position: relative / position: absolute on a <th> or <td> in Firefox it doesn't seem to work.

Ben Johnson
  • 2,572
  • 3
  • 19
  • 19
  • 3
    Nope, I think no browser supports that properly. It's not legal in any HTML standard AFAIK – Pekka Feb 28 '11 at 21:58
  • Can you elaborate? Are you trying to position the elements inside of the itself? You can float elements inside 's and 's. Post some sample code. – dmackerman Feb 28 '11 at 21:58
  • 2
    @Pekka: HTML doesn't come into it, this is CSS. And amazingly, it works. :-) – T.J. Crowder Feb 28 '11 at 22:08
  • 15
    Works in WebKit and IE as far as I can tell. Firefox seems to be the only one who doesn't like it on table-cells. And yes, I'm trying to position elements inside of the without having to rely on floats. – Ben Johnson Feb 28 '11 at 22:18
  • 2
    Again, look at Justin's answer. It works just fine in Firefox if you tell Firefox that you're treating it as a block rather than as a table element. – T.J. Crowder Feb 28 '11 at 22:19
  • Yeah, I'm trying to set `position: relative` on a table cell so that blocks within the cell can be `position: absolute` (ie. always along the bottom of the cell). Have tried everything listed in this thread, but nothing works (setting cells to `display: block` completely ruins the layout, and getting floats to all be the same fluid height is really painful). JS might be the only option. – Simon East Jul 20 '11 at 04:12
  • so, only google goes for li instead of table for their image search? –  May 02 '12 at 07:02
  • 1
    A jsfiddle demonstrating the problem in this question: http://jsfiddle.net/M5P93/ Works in IE, Safari, Chrome; Firefox fails. – Chris Moschini Aug 03 '12 at 21:09
  • Just want to point out that, legal or not, this works in every browser that supports CSS tables except for FireFox, even most mobile browsers too. FireFox should fix this. – mrbinky3000 Oct 23 '12 at 14:19
  • This shows the problem well if you look at it in firefox and webkit. I have yet to find a good answer. http://jsfiddle.net/2xYmG/ – Joel Drapper Apr 27 '12 at 13:04
  • 1
    It's a 14-year-old bug: https://bugzilla.mozilla.org/show_bug.cgi?id=35168 – fregante Jan 10 '14 at 22:55
  • FWIW: In addition to actual table elements, this bug also applies (in Firefox) when an element has CSS: `display:table` - see this [fiddle](http://jsfiddle.net/danield770/vQ8Kk/1/) - It works in webkit and IE, but not in FF – Danield Feb 02 '14 at 11:20
  • 1
    It is a known bug to Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=35168 – Markus Apr 14 '14 at 09:53

9 Answers9

166

Easy and most proper way would be to wrap the contents of the cell in a div and add position:relative to that div.

example:

<td>
  <div style="position:relative">
      This will be positioned normally
      <div style="position:absolute; top:5px; left:5px;">
           This will be positioned at 5,5 relative to the cell
      </div>
  </div>
</td>
DavidJonas
  • 1,708
  • 1
  • 11
  • 2
  • 11
    +1 This is the only solution that worked for me. Using `tr {display:block}` completely ruins the layout. – Wesley Murch Dec 14 '11 at 21:30
  • +1 This is the answer for me as well. `display: block` isn't enough of a fix on complex table layouts. The extra div is solution that is more reliable. – DA. Apr 18 '12 at 04:49
  • 5
    but, with this solution "width" and "height" still can't be used – 4esn0k May 16 '12 at 07:58
  • @4esn0k did you find a solution where you can use width and height? – Neil Jun 20 '12 at 14:40
  • @Neil, i was wrong, widht 100% can be used; other solution is to use flex-box, may be – 4esn0k Jun 22 '12 at 03:58
  • A jsfiddle demonstrating this solution: http://jsfiddle.net/M5P93/1/ - works in Firefox, as well as IE, Safari, Chrome – Chris Moschini Aug 03 '12 at 21:09
  • 9
    Unfortunately, your solution does **not** work if you add another column with more content in it than in the other one. So I do not understand the "accepted answer" flag and the much appreciation given by the votes up. Please check http://jsfiddle.net/ukR3q/ – Jan Apr 29 '13 at 17:05
  • Wow. I was trying to do this and the solution is stupid simple. How I didn't think of it is unknown to me. – tomysshadow Nov 13 '14 at 05:52
  • Adding `height:100%` to your tr, td and div fixes the problem many are describing regarding column height - @Jan, Unfortunately only in FF though, hopefully might help someone though. http://jsfiddle.net/gvcLoz20/ – Ben Jul 06 '15 at 13:21
34

That should be no problem. Remember to also set:

display: block;
Justin Niessner
  • 229,755
  • 35
  • 391
  • 521
  • Wow, +1. Example: http://jsbin.com/apeka4 Works in Chrome, Firefox, Opera, even IE (even *IE6*). Without the `display: block;` (http://jsbin.com/apeka4/2) it varies. – T.J. Crowder Feb 28 '11 at 22:02
  • 32
    The downside to setting display: block seems to be that it can really mess with table formatting if it's applied directly to the element. Because it's changing it from table-cell... or am I crazy? – Ben Johnson Feb 28 '11 at 22:15
  • 3
    @Ben: Well, yeah. Setting `position` on a table cell is, by definition, seriously changing the table formatting. You take the cell's block out of the flow (except for `position: relative`, where it stays in the flow but offsets from it). – T.J. Crowder Feb 28 '11 at 22:16
  • 2
    @Ben - Nope, not crazy. You'll definitely have to do some more work to get things looking the way you want. The point is merely that it is possible. – Justin Niessner Feb 28 '11 at 22:17
  • It's nice to know it's possible, but it sounds like most of the time the best solution would be to just throw an extra element in there. – Ben Johnson Feb 28 '11 at 22:20
  • 1
    @TJ It's not adding position: relative that's changing the visual appearance, it's changing the th/td from table-cell to block. Again, nice to know that it works, but in a lot of cases creating block level elements will really mess with table formatting. Thanks Justin! – Ben Johnson Feb 28 '11 at 22:27
  • @Ben: With respect, it *is* the `position` property that's taking it out of the flow (look up `position` in the CSS spec). Firefox seems to need the extra `display: block` hint, but from a flow perspective, `position` should have been sufficient (although you can totally see the Firefox perspective on it; it's *weird* to have *positioned* non-block elements). – T.J. Crowder Feb 28 '11 at 22:38
  • @TJ When I refer to 'visual appearance', I'm talking about this: http://jsfiddle.net/QbFwV/ Position: relative does remove it from the normal flow, but it sets it relative to the normal position, so there's no visual problems. Changing a table cell from table-cell to block does come with it's own styling issues though. That was my point. – Ben Johnson Mar 01 '11 at 16:57
  • In my case, this is exactly what I needed. Thanks! – Brian Moeskau Jan 25 '12 at 19:47
  • I arrived at the conclusion that Firefox ignoring a `position: relative` on a `td` is a bug, which I am arguing here: http://wiki.orbeon.com/forms/doc/contributor-guide/browser#TOC-Firefox-doesn-t-support-position:-r – avernet Feb 17 '12 at 02:52
  • 9
    alas, `display: block` can also cause issues in Firefox--namely if the table cell is spanning columns, setting it to block will collapse the cell down to the first column. – DA. Apr 18 '12 at 04:45
  • Same behavior occurs when `display: table-cell;` is used. Any idea how to fix this? – Starx Aug 28 '13 at 03:27
  • This doesn't solve the proposed problem as it fundamentally changes the way the table cell is displayed. – Akrikos Mar 04 '14 at 16:45
13

Since every web browser including Internet Explorer 7, 8 and 9 correctly handle position:relative on a table-display element and only FireFox handles this incorrectly, your best bet is to use a JavaScript shim. You shouldn't have to rearrange your DOM just for one faulty browser. People use JavaScript shims all the time when IE gets something wrong and all the other browsers get it right.

Here is a completely annotated jsfiddle with all the HTML, CSS, and JavaScript explained.

http://jsfiddle.net/mrbinky3000/MfWuV/33/

My jsfiddle example above uses "Responsive Web Design" techniques just to show that it will work with a responsive layout. However, your code doesn't have to be responsive.

Here is the JavaScript below, but it won't make that much sense out of context. Please check out the jsfiddle link above.

$(function() {
    // FireFox Shim
    // FireFox is the *only* browser that doesn't support position:relative for
    // block elements with display set to "table-cell." Use javascript to add
    // an inner div to that block and set the width and height via script.
    if ($.browser.mozilla) {

        // wrap the insides of the "table cell"            
        $('#test').wrapInner('<div class="ffpad"></div>');

        function ffpad() {
            var $ffpad = $('.ffpad'),
                $parent = $('.ffpad').parent(),
                w, h;

            // remove any height that we gave ffpad so the browser can adjust size naturally.
            $ffpad.height(0);

            // Only do stuff if the immediate parent has a display of "table-cell".  We do this to
            // play nicely with responsive design.
            if ($parent.css('display') == 'table-cell') {               

                // include any padding, border, margin of the parent
                h = $parent.outerHeight();

                // set the height of our ffpad div
                $ffpad.height(h);

            }

        }


        // be nice to fluid / responsive designs   
        $(window).on('resize', function() {
            ffpad();
        });

        // called only on first page load
        ffpad();

    }

});
mrbinky3000
  • 3,505
  • 8
  • 37
  • 52
11

Starting with Firefox 30, you'll be able use position on table components. You can try for yourself with the current nightly build (works as standalone): http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-trunk/

Test case (http://jsfiddle.net/acbabis/hpWZk/):

<table>
    <tbody>
        <tr>
            <td style="width: 100px; height: 100px; background-color: red; position: relative">
                <div style="width: 10px; height: 10px; background-color: green; position: absolute; top: 10px; right: 10px"></div>
            </td>
        </tr>
    </tbody>
<table>

You can continue to follow the developers' discussion of the changes here (the topic is 13 years old): https://bugzilla.mozilla.org/show_bug.cgi?id=63895

Judging by recent release history, this could be available as soon as May 2014. I can barely contain my excitement!

EDIT (6/10/14): Firefox 30 was released today. Soon, table positioning won't be an issue in major desktop browsers

aebabis
  • 3,392
  • 3
  • 18
  • 39
7

As of Firefox 3.6.13, position: relative/absolute do not seem to work on table elements. This seems to be long standing Firefox behaviour. See the following: http://csscreator.com/node/31771

The CSS Creator link posts the following W3C reference:

The effect of 'position:relative' on table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, and table-caption elements is undefined. http://www.w3.org/TR/CSS21/visuren.html#positioning-scheme

Ben Johnson
  • 2,572
  • 3
  • 19
  • 19
  • See Justin's answer. It works, provided you change the `display` setting. Which makes sense (to the degree CSS makes sense). – T.J. Crowder Feb 28 '11 at 22:03
  • 8
    Yeah, it "works" except that applying it to cells completely wrecks your table... Kinda pointless in that instance. – Simon East Jul 20 '11 at 04:09
3

Try using display:inline-block it worked for me in Firefox 11 giving me positioning capability within the td/th without destroying the layout of the table. That in conjunction with position:relative on a td/th ought to make things work. Just got it working myself.

1

I had a table-cell element (which was actually a DIV not a TD)

I replaced

display: table-cell;
position: relative;
left: .5em

(which worked in Chrome) with

display: table-cell;
padding-left: .5em

Of course padding usually is added to width in the box model - but tables always seem to have a mind of their own when it comes to absolute widths - so this will work for some cases.

Simon_Weaver
  • 120,240
  • 73
  • 577
  • 618
0

Adding display:block to the parent element got this working in firefox. I also had to add top:0px; left:0px; to the parent element for Chrome to work. IE7, IE8, & IE9 are working as well.

<td style="position:relative; top:0px; left:0px; display:block;">
    <table>        
        // A table of information here. 
        // Next line is the child element I want to overlay on top of this table
    <tr><td style="position:absolute; top:5px; left:100px;">
        //child element info
    </td></tr>
   </table>
</td>
Community
  • 1
  • 1
GrantE
  • 139
  • 1
  • 6
0

The accepted solution kind of works, but not if you add another column with more content in it than in the other one. If you add height:100% to your tr, td & div then it should work.

<tr style="height:100%">
  <td style="height:100%">
    <div style="position:relative; height:100%">
        This will be positioned normally
        <div style="position:absolute; top:5px; left:5px;">
             This will be positioned at 5,5 relative to the cell
        </div>
    </div>
  </td>
</tr>

The only problem is that this only fixes the column height problem in FF, not in Chrome and IE. So it's a step closer, but not perfect.

I updated a the fiddle from Jan that wasn't working with the accepted answer to show it working. http://jsfiddle.net/gvcLoz20/

Ben
  • 1,841
  • 20
  • 24