jkelley
jkelley

Reputation: 2640

CSS Positioning inside of an HTML Table

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?

Upvotes: 2

Views: 20021

Answers (7)

Thomas W
Thomas W

Reputation: 14164

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?

Upvotes: 0

WebManWalking
WebManWalking

Reputation: 69

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.

Upvotes: 3

robertc
robertc

Reputation: 75707

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>

Upvotes: 2

scronide
scronide

Reputation: 12238

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;
}

Upvotes: 2

Guffa
Guffa

Reputation: 700192

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

Upvotes: 2

Wouter van Nifterick
Wouter van Nifterick

Reputation: 24086

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>

Upvotes: 0

Daniel Elliott
Daniel Elliott

Reputation: 22857

try in CSS

.aRelativelyPositionedClass td {
   // your style 
}

I believe you would have to explicitly state relative too.

Upvotes: 1

Related Questions