I have a table like this:
<table cellspacing="0">
<tr>
<td>Row 1</td>
<td><button>Button 1</button></td>
</tr>
<tr>
<td>Row 2</td>
<td><button>Button 2</button></td>
</tr>
<tr>
<td>Row 3</td>
<td><button>Button 3</button></td>
</tr>
</table>
I wanted to absolutely position each button at the top right of the table row, so I used this CSS, expecting the <tr>
to contain the <button>
:
tr {
position:relative;
}
button {
position:absolute;
top:0;
right:0;
}
However, the buttons are all stacked on top of each other in the same place. It normally works fine using <div>
s, except it will still behave this way when using display:table-row
which I found out while testing, and came as a surprise to me.
Demo: http://jsfiddle.net/QU2zT/1/
Note: My actual markup is more complex, and the element I'm trying to position might appear anywhere in any table cell in it's row, which is why I believe I need position:absolute
.
EDIT: The results are different in Firefox than they are in Chrome and IE9 (haven't tested beyond that). FF is a complete failure, while the other browsers only fail to contain the "divs with table display" setup, seen in the demo.
If you are placing an element with absolute position, you need the base element to have a position value other than the default value. In your case if you change the position value of the parent div to 'relative' you can fix the issue.
Generally speaking, float is a relative positioning statement, since it specifies the position of the element relative to its parent container (floating to the right or left). This means it's incompatible with the position:absolute property, because position:absolute is an absolute positioning statement.
Absolute An element with position: absolute is removed from the normal document flow. It is positioned automatically to the starting point (top-left corner) of its parent element. If it doesn't have any parent elements, then the initial document <html> will be its parent.
Fixed. The fixed value is similar to absolute as it can help you position an element anywhere relative to the document, however this value is unaffected by scrolling.
Use this hack as position: relative
is ignored in <tr>
(thanks to https://github.com/w3c/csswg-drafts/issues/1899)
tr {
transform: scale(1);
}
td {
position: absolute;
top:0;
right:0
}
To quote from the spec:
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.
EDIT:
The only solution that I can see involves using :last-child
(ie. no IE < 9) and good old vertical-align
and text-align
:
td:last-child {
vertical-align: top;
text-align: right;
padding: 0;
margin: 0;
}
Here's a working demo: http://jsfiddle.net/QU2zT/15/
I would also like to add that if you really don't want to change your markup and need to support IE you can use this solution combined with JavaScript.
PS: I haven't looked at (and won't comment on) the solution using div
s as I see no point in writing that much markup to obtain a table
, when there is already one. It will only be a maintenance nightmare.
Apparently, the only pure CSS solution is to set display:block
on the tr
(including implicitly via use of float
). However, this severely breaks table layouts and didn't work out very well for me.
I decided to bite the bullet and wrap the content of the cell in a div
, as suggested in these answers:
<tr>
<td>
<div style="position:relative">
<button style="position:absolute"></button>
</div>
</td>
</tr>
This still has a disadvantage: since our position:relative
element must be inside a table cell, it only works in the last cell of the table row (when the goal is to have the absolute element positioned relative to the entire row, in the top right corner). This also doesn't seem to position the element correctly as seen here: http://jsfiddle.net/QU2zT/25/
This seems to be the best we can do, without abandoning table markup or breaking it's rendering.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With