2

I feel like this should be a no brainer, but clearly I'm missing something...

I'm stuck with an HTML table on a page, and need to absolutely position an element that is rendered inside of the table so that it can display properly when we apply DHTML to show it.

I tried absolutely positioning it relative to the bottom of a table row, but the browser (FF and IE) will not render it relative to the row. Instead it takes the positioning relative to the next parent above the row that has relative positioning.

Basically it is:

<table>
<tr class="aRelativelyPositionedClass">
    <td>
         <div class="anAbsolutelyPositionedClass">stuff I want to absolutely position</div>
    </td>
</tr>
</table>

Is it possible to position the inner div relative to the row? Or is there an HTML issue I'm missing with tables?

jkelley
  • 2,570
  • 3
  • 21
  • 24

7 Answers7

3

According to the http://www.w3.org/TR/CSS2/visuren.html#choose-position discussion of relative: "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."

The problem is that Firefox, Google Chrome, Opera and Safari have chosen for position:relative to do nothing on a table-row. IMHO, they should have implemented the change of frame-of-reference, so that absolutely-positioned subelements will be rendered relative to the table-row, but they didn't.

My need to absolutely-position elements in a row occurred in JavaScript, so I had an easy solution. If the element's display is table-row, change it to block, THEN set position:relative. I realize this doesn't help you if you're trying to do it all soley using HTML and CSS. But in my situation, setting display:block before position:relative worked.

2

If there's nothing else in the table cell apart from the div you want to position, it's possible that it's collapsing to zero dimensions when you move the div out of the flow with the absolute positioning, and this is throwing your calculations out. Is there an explicit height set on the row or the cell?

Edit: I think Guffa is correct. With just one div in the cell I couldn't get it to position relative to either the row or the cell. I think you could fake the effect you're looking for by adding some markup:

<table border="1">
    <tr style="position:relative;">
        <td><img src="http://sstatic.net/so/img/so/logo.png" height="61px" width="250px" alt=""/></td>
        <td>
            <div style="position: relative; height: 100px; width: 100px;">
                <div style="border: 1px solid red; position: absolute; bottom: -10px; left -10px;">Position me</div>
            </div>
        </td>
    </tr>
</table>
robertc
  • 74,533
  • 18
  • 193
  • 177
  • Sadly, there is plenty in the row which will keep it from collapsing. The row does have a valid height (approx 60px), so it must be something with the way the browsers interpret positioning within tables. – jkelley Aug 14 '09 at 21:06
  • Not by me, I think you're response was correct in the case where no other data is in the cell – jkelley Aug 14 '09 at 22:28
  • Probably some people some people are just offended at how nasty the code gets once you start mixing table based and css layout :) – robertc Aug 14 '09 at 22:44
2

I don't think that you can position it relative to the row, as the row is not really a visible element.

You should be able to position it relative to the cell by setting the style position:relative on the cell to make it a layer. Still the cell is not an independent element, so you may have to put another div in the cell and make that a layer instead to make it work properly.

(Tables are problematic for layout when you combine it with other techniques... Perhaps you should consider removing the table altogehter...)

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • yes, I'd like to remove the table, but for now we are stuck with it in the page. I may have to end up using an independent div. When I do this, though, the other table elements still sit over the div (like the select input issue with DHTML overlays). Any way to place the layer clearly over the table layers, or is this beyond css control? – jkelley Aug 14 '09 at 21:15
  • OK - false alarm on the issue of other table elements overlaying the absolutely positioned items. It was due to the other relatively positioned divs from each row, not the table itself. – jkelley Aug 14 '09 at 21:20
2

CSS 2.1 Specification:

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.

So the browsers fall back to the next parent whose behavior is considered defined: table.

One solution is to force those rows to display as blocks:

tr.aRelativelyPositionedClass {
    display: block;
}
scronide
  • 12,012
  • 3
  • 28
  • 33
  • Good idea - this works great in FF, but doesn't seem to agree with IE. I think I'll have to hack it in using extra markup in the cell per Guffa – jkelley Aug 14 '09 at 21:41
  • See my answer: Put a DIV position=relative, immediately inside the TD! It's a correct solution & works, no hack required. – Thomas W Feb 10 '13 at 02:59
  • This should be the right answer to add display:block to the TR. In my case, it also worked when the display:block is added to TD. However, this seems to be required ONLY by FF. In Chrome, IE, even Safari, the absolute position works the way intended. This fix is not needed in those browsers. – devXen Feb 23 '13 at 19:35
1

try in CSS

.aRelativelyPositionedClass td {
   // your style 
}

I believe you would have to explicitly state relative too.

Daniel Elliott
  • 22,647
  • 10
  • 64
  • 82
  • i tried this - FF didn't honor the class, but IE did. Unfortunately, IE also makes the remainder of the table sit on a layer above the div I'm absolutely positioning, seemingly regardless of what I do w/ the z-index property. – jkelley Aug 14 '09 at 21:13
0

Paste this in a file to see how it's done.

Remember to set the container's size. I did it in HTML here to keep the example short, but you should do that in CSS.

<table border="1" width="500">
<tr height="200">
    <td>
         <div style="position:relative;top:20;left:20">stuff I want to position</div>
         <div style="position:relative;top:30;left:30">stuff I want to position</div>
         <div style="position:relative;top:40;left:40">stuff I want to position</div>
         <div style="position:relative;top:50;left:50">stuff I want to position</div>
    </td>
</tr>
<tr height="200">
    <td>
         <div style="position:relative;top:20;left:20">stuff I want to position</div>
         <div style="position:relative;top:30;left:30">stuff I want to position</div>
         <div style="position:relative;top:40;left:40">stuff I want to position</div>
         <div style="position:relative;top:50;left:50">stuff I want to position</div>
    </td>
</tr>
</table>
Wouter van Nifterick
  • 23,603
  • 7
  • 78
  • 122
0

The solution is very simple: Put a DIV position=relative, immediately inside the TD.

TR and TD elements don't support 'position' being set -- so they can't be properly set to 'position=relative', to be the container for your positioning.

This is CSS specification & browsers use special CSS position-values to implement row & cell behaviour of the table.

<td>
  <div style='position:relative;'>  <!-- relative container for positioning -->
    <!-- DIVs to be positioned, go in here. -->
  </div>

See also: Using Position Relative/Absolute within a TD?

Community
  • 1
  • 1
Thomas W
  • 13,940
  • 4
  • 58
  • 76
  • 1
    Why downvote? The answer's exactly correct, clear & I've used it to solve this exact same problem myself. – Thomas W Sep 26 '13 at 23:44