CSS Positioning inside of an HTML Table - html

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?

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.

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

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

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>

try in CSS
.aRelativelyPositionedClass td {
// your style
}
I believe you would have to explicitly state relative too.

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>

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?

Related

Contain absolutely positioned 100% width DIV inside a TD in Firefox

I found several questions addressing similar problems, but each solution has a particularity that prevents it from applying to this situation...
My issue is that I want an absolutely positioned, 100% width, div inside a table cell. I can't use fixed widths or heights anywhere because all the content can vary in width and height. I want the div to be positioned from the bottom of the cell height, which is influenced by the (variable) height of the content in the next cell.
The code below works fine in IE8 (yeah, still have to support it...), IE11 and Chrome — the red div stays contained within the left table cell. In Firefox however, the div is actually sized according to the width of the TABLE, covering part of the cell on the right.
What can I do to make it work in Firefox?
Demo: http://jsfiddle.net/AGYGH/
HTML:
<table id="OuterTable" border="1">
<tr>
<td id="TableCell">
<table id="InnerTable" border="1">
<tr>
<td>Dummy text of varying length</td>
<td>Dummy</td>
</tr>
</table>
<div id="AbsoluteDiv">
<div id="InnerDivLeft">Left Div</div>
<div id="InnerDivRight">Right Div</div>
</div>
</td>
<td>
<select multiple="multiple" size="10">
<option>Varying length options</option>
</select>
</td>
</tr>
</table>
CSS:
#OuterTable {
position:relative;
}
#TableCell {
vertical-align:top;
position:relative;
}
#AbsoluteDiv {
background-color:red;
position:absolute;
width:100%;
bottom:30px;
}
#InnerDivLeft {
float:left;
}
#InnerDivRight {
float:right;
}
I've ran into this problem as well. According to the spec, table cells cannot be positioned. Meaning FireFox is doing it right, and everyone else is doing it "right".
Kinda hacky, but you could always use div's with "display: table-cell" THEN position them relative.
This article has a good JS alternative for the issue.
Thanks to Seth for pointing me to the JavaScript solution, which has the added benefit of also fixing small padding/margin issues on IE in my 'real world' usage.
So, I've wrapped the entire content of <td id="TableCell"> with a <div class="wrapper"> (as suggested by Hashem) and used jQuery to size its height to the actual height of the table cell:
$('#TableCell div.wrapper').height($('#TableCell').height());
Revised Demo (with the added wrapper colored blue) : http://jsfiddle.net/AGYGH/9/

CSS relative positioning, make all children relative to parent

Please consider the following HTML with styling.
<div style="border: 1px solid;height: 600px;">
<button id="create_new_estimate" style="position:relative;top:10px;left:10px;">
Create New Estimate
</button>
<table style="position:relative;top:10px;left:300px;">
<tr>
<td>
cell 1
</td>
</tr>
<tr>
<td>
cell 2
</td>
</tr>
</table>
</div>
You can see it here.
I want to be able to position both of these elements side by side. Eventually I will be adding many more elements inside this div. I thought that position:relative would allow me to just give a top and left style attribute to each element to give it a position relative to the parent div. However as you can see in this example, both elements have top:10px; so I would expect them to be next to each other, but they are not next to each other.
Do you know how what styling I can use, so I can simply give each element a top and left attribute to position them inside the parent. Thanks!
Give you outter wrap div a "position:relative;" and change you current "position:relative;" to "position:absolute;"
Use "top" and "left" attributes alongside the "position:absolute" and think of "position:relative" as your anchor. It you don't have a parent element with "position:relative" then the browser window becomes your anchor.

Make div width adapt automatically to contents within it

I have a div within which a table would lie. Now I want this div to have its width set automatically to the width of table within it.
For example:
<div>
<table>
<tr>
<td>Hello</td>
<td>World</td>
</tr>
<tr>
<td>Sample</td>
<td>Table</td>
</tr>
</table>
</div>
I tried giving float: left; property to it. It works, but then it creates another problem. Whatever content is put after this div gets placed to the right of it in the empty space.
What needs to be done?
You are effectively attempting to change the display model of that div element, so you should change it's CSS 'display' property as follows:
div{
display: inline-block;
}
Here's a jsFiddle demonstrating the solution.
You have to clear the float after your div by adding style="clear: left;" on your consecutive element:
<div style="float: left;">
<table>...</table>
</div>
<div style="clear: left;">
...
</div>
This is quite new but...
If you don't want the element to become inline-block, you can do this:
.parent{
width: min-content;
}
You have a lot of other options for configuring the width. Read more here: http://caniuse.com/#search=intrinsic
You need to clear the float explicitly in order to not impair subsequent elements by the float. See this article for details.
If i understand correctly, you want the div to be as wide as the table but not any wider. Since the div-element is a block element, it will always be as wide as it can be unless you give it an explicit width.
Your choice is to either add the style display:inline or use an inline-element like "span".

Table doesn't want to stretch inside div

I have a <table> inside a <div> tag, which doesn't want to span as long as it needs to be. I need to specify a width in px for the <table> to span and thus cause the <div> container it is inside to scroll. Otherwise, the <table> just spans to a width of 100%, i.e. the width of the <div>.
My example is as follows:
<div style="width:880px; overflow:scroll;">
<table> // I need to explicitly specify a width for it, otherwise it just span 100% which is incorrect
<tr><td></td><td></td><td></td></tr>
</table>
</div>
I have specified for all the <td> tags a width inside my CSS.
I don't understand why the <table> can't determine it's own width or just respect the widths of all the <td> tags.
Try setting white-space: nowrap; on the td in your table and dump a lot of text inside each td you will start seeing a scroll bar on your div.
Are you sure there isn't any unintended CSS being applied to the table? By default the table only expands to accommodate its columns.
<div style="width:880px; overflow:scroll; background-color: green;">
<table style="background-color: red;">
<tr>
<td>one</td>
<td>two</td>
</tr>
</table>
</div>
Using this code, you can see the red table is only as big as its columns in relation to the green div as long as no other CSS is involved.
Use a tool like Firebug or IE's Developer Tools (F12) to see which styles are actually being applied to the table element.
See the example here.

Not able to move DIV around

I have the following code:
<textarea>
<td align="center" bgcolor="#996633" onMouseover=javascript:ShowContent("menu7_items") onMouseout=javascript:HideContent("menu7_items")>
<p> Stock Update </p>
<div id="menu7_items" style="display:none;" onMouseover=javascript:ShowContent("menu7_items") onMouseout=javascript:HideContent("menu7_items")>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td align="left">Update Paper</td>
</tr>
</table>
</div>
</td>
</textarea>
There is a TD inside which there is a DIV and inside DIV there is a Table. DIV's default style is display:none. On mouseover TD, the div should appear like a popup in a given position. But it is not happening. DIV is appearing in the same TD. How to make DIV's position independent of TD.
position: absolute;
You may also want to specify the direction properties (top, right, bottom, left), but try it without those first to see how it looks. If you use them, you may want to use position: relative on the parent to position the absolute child relative to it (the same works with any position value that isn't "static", the default).