I have an issue, described in title. I have a table, div inside td of this table.
I want to position this div relative to table row, so I set tr position to relative and div position to absolute. It works fine in Firefox, but in IE it works unexpectedly for me.
There is a code:
<div class="container">
<div class="panel"></div>
<table>
<tbody>
<tr>
<td>a</td>
<td>s</td>
<td><div class="problem-div">i'm here</div></td>
</tr>
</tbody>
</table>
table {
border: 1px solid;
table-layout: fixed;
width: 100%
}
tr {
position: relative
}
.panel {
height: 50px;
background-color: red
}
.problem-div {
position: absolute;
top: 0;
left: 0
}
There is fiddle
http://jsfiddle.net/L7nczrsp/5/
Help me to understand what I'm doing wrong, please.
UPDATE1
Thanks to #James we now know that position for table elements is undefined http://w3.org/TR/CSS21/visuren.html#propdef-position
But, we can set td position to relative instead of setting this styles to tr. It works fine. But it still conflicts with w3.
But Thanks to #ShabanKhan for idea, we can put relative positioned div into td and put our problem-div into this div. Seems to work. There is updated fiddle http://jsfiddle.net/meatwas/akkLxjpp/1/
Positioning do not work on table properties try to add a div to make it position relative.
If you add position: relative to the table, so it works well in Chrome, FF and Safari
There is your on jsfiddle example with this idea.
Related
I have recreated a CSS compatibility issue I have come across between Chrome and Firefox.
An "inner" DIV with 100% height inside a Table cell which is inside a "container" DIV of fixed height. I want the inner DIV to fill the cell and dynamically add text to it such that a scrollbar appears when it begins to overflow.
In the JSFiddle you can see the code in both Chrome and Firefox. In Chrome it behaves as expected but in Firefox the scrollbar doesn't display and the inner DIV just keeps expending beyond the height of the container DIV.
JSFiddle code to try in both Chrome and Firefox
HTML as follows:
<style>
#container {
height:80px;
width:100%;
border:1px solid;
overflow:hidden;
resize:vertical;
}
#inner {
height:100%;
width:300px;
border:2px solid red;
overflow-y:auto;
}
table{
height:100%;
}
</style>
<div id="container">
<table>
<tr>
<td>
<div id="inner">
Test<br/>Test<br/>Test<br/>Test<br/>Test<br/>
</div>
</td>
<td>
<img src="https://doc-snapshots.qt.io/qt-mobility/images/used-in-examples/video/qmlvideo/images/close.png" />
</td>
</tr>
</table>
</div>
EDIT, further requirement: I forgot to mention that I have this setup inside a resizable DIV i.e. the Container DIV is able to resize it's height so that the table and Inner DIV resize accordingly.
Thats a common mistake. Whenever an element is set to height: 100% or any other percentage, it relates to the height of its parent. So when using this, its important to define a height for the parent of your element:
To demonstrate the problem: Adding a class to the parent <td class="fix"> and add some css fixes the problem:
.fix {
height: 80px;
display: block;
}
WORKING JSFIDDLE DEMO
Keep in mind that setting the display attribute of a table cell from table-cell to block is something you should avoid, as you are changing the elements roots. Consider a solution without using a <table> markup if you have got the possibilities.
#inner {
border: 2px solid red;
height: 75px;
overflow: auto;
width: 300px;
}
You can use this CSS. I think it may work fine.
I'm trying to fill the center cell of a table with a div element. For the purposes of illustrating the problem, the div is styled with a red background. It seems to work in Chrome, but not IE. In the fiddle below, IE is setting the height of the div to the minimum height necessary to contain its content. In tinkering around with this problem with different CSS settings, I managed to get IE to interpret "height: 100%"; as "the height of the browser window". However, as the question states, I want IE to interpret it as the height of the td cell. Any ideas?
http://jsfiddle.net/UBk79/
CSS:
*{
padding: 0px;
margin: 0px;
}
html, body{
height: 100%;
}
#container{
height:100%;
width: 100%;
border-collapse:collapse;
}
#centerCell{
border: 1px solid black;
}
#main{
height: 100%;
background-color: red;
}
HTML:
<table id="container">
<tr id="topRow" height="1px">
<td id="headerCell" colspan="3">
TOP
</td>
</tr>
<tr id="middleRow">
<td id="leftCell" width="1px">
LEFT
</td>
<td id="centerCell">
<div id="main">CENTER</div>
</td>
<td id="rightCell" width="1px">
RIGHT
</td>
</tr>
<tr id="bottomRow" height="1px">
<td id="footerCell" colspan="3">
BOTTOM
</td>
</tr>
</table>
I did some more research on this and collected some info that might come in handy to others trying to solve similar problems. The CSS spec says the following three things that I think are important:
First, re: specifying the height (of a div) as a percentage:
The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.
http://www.w3.org/TR/CSS21/visudet.html#the-height-property
... a height of 'auto' won't fill the cell unless the content is taller than the cell's minimum height. But if we try to explicitly set the height of the containing cell or row, then we run into the following problem:
CSS 2.1 does not define how the height of table cells and table rows is calculated when their height is specified using percentage values.
http://www.w3.org/TR/CSS21/tables.html#height-layout
Since the spec doesn't define it, I guess it's not too surprising that Chrome and IE choose to calculate it differently.
Alternatively, (as xec indirectly pointed out) trying to use relative positioning has the following spec problem:
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.
www.w3.org/TR/CSS21/visuren.html#propdef-position
So I've concluded there's probably not a pure CSS way to solve the problem that one can reasonably expect to work on most browsers.
At first, I thought, "Wow, the CSS spec is pretty shoddy and incomplete for leaving all this stuff undefined." As I thought about it more, though, I realized that defining the spec for these issues would a lot more complicated than it appears at first. After all, row/cell heights are calculated as a function of the heights of their content, and I want to make the height of my content a function of the row/cell height. Even though I have a well-defined, terminating algorithm for how I want it to work in my specific case, it's not clear that the algorithm would easily generalize to all the other cases that the spec would need to cover without getting into infinite loops.
Just set the table cell to: position:relative and the div to:
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
Edit 2017:
DEMO BELOW:
Note how you cannot see the red td because the yellow div covers it entirely...
#expandingDiv {
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
background: yellow;
}
<table style="width: 120px">
<tr>
<td style="background: blue">blue td</td>
<td style="background: green">green td</td>
</tr>
<tr>
<td style="background: red; position: relative">
<div id='expandingDiv'> yellow div </div>
</td>
<td style="background: orange">
Some longer text which makes the bottom two tds expand dynamically.
</td>
</tr>
</table>
Although I liked Craig's answer and will not use the approach in this answer myself, I did get quite far with this jsFiddle.
It relies on a hack, however: Setting height: 1px on the table. It works in Chrome, FF, IE11 and Edge (all that I tested), but Chrome starts misbehaving in edge cases. See the fiddle. Here are the interesting bits:
table {
width: 100%;
/* Whý does this make it work? */
height: 1px;
}
td {
border: 10px solid blue;
height: 100%;
}
#container {
width: calc(100% - 20px);
height: calc(100% - 20px);
border: 10px solid black;
}
Too much of a hack-smell to me.
have you tried changing css to:
#centerCell{
border: 1px solid black;
height:100%;
}
seems to work for me on edge, firefox and chrome
Simply set the line height of the div; as long as its display is still a block level element. There is no need for relative or absolute positioning or hard coding of the height at the div level or any of its parents. Works in IE 8+, Firefox, and Chrome.
Example:
line-height: 50px;
// or
line-height: 2em;
Here's a jsfiddle: https://jsfiddle.net/55cc077/pvu5cmta/
CSS height: 100% only works if the element's parent has an explicitly defined height. This jQuery sets the table cell height in the first column.
<script type="text/javascript">
$(function(){
$('.myTable2 tr').each(function(){
var H1 = $(this).height(); // Get the row height
$(this).find('td:first').css({'height': H1 + 'px', 'line-height': H1 + 'px'}); //Set td height to row height
});
});
</script>
Html:
<br/><br/><br/><br/><br/>
<table>
<tr>
<td class="container">
<button class="del">delete</button>
</td>
</tr>
</table>
<br/><br/><br/><br/><br/>
<div class="container">
<button class="del">delete</button>
</div>
Css:
.container {
position: relative;
border: 1px solid red;
height: 50px;
width: 200px;
}
.del {
position: absolute;
top: 3px;
right: 3px;
}
Why the button inside a div will be placed on the top right corner of the div, but the one inside a td will be placed outside the table?
How to fix it?
See active demo: http://jsfiddle.net/Freewind/d6Tug/
I think it has something to do with the display style of a td, which is table-cell. If you set it to display:block, it will work correctly.
Just add display:block to your .container style.
As freewind pointed out, it would be better to use inline-block if it is supported in your browser for td since td's are usually displayed in a row.
Giving an element position:absolute; places it relative to its containing block. Since a table cell is not considered a block container (unlike a div), it places it relative to the document body itself. top:3px; brings it 3px from the top border of the document and right:3px; moves it 3px from the right border.
http://reference.sitepoint.com/css/position
I have a table with 3 columns and first and third column are divided by a vertical line for which i used table with with 100% height and background color which works in fine in FF but doesn't work in Chrome or IE.
Now i replace the table with div tag but empty div doesn't show up. Below is the sample code i tried so many thing now i am confused what to use. Need help from CSS Gurus.
.PageLine2V
{
width:2px;
content: "";
min-height: 100%;
background-color:#D1C094;
background-image:url('../images/gold-line-2v.gif');
background-repeat:repeat-y;
}
<table height="100%">
<td width="60px" valign="top" align="center" >
<div class="PageLine2V"></div>
</td>
</table>
I am not sure how i can make this empty div show up and grow with table height also
.PageLine2V
{
width:2px;
content: "";
min-height: 100%;
background-color:#D1C094;
background-image:url('../images/gold-line-2v.gif');
background-repeat:repeat-y;
height: 100%;
}
Give the div a height of 100%
Also add something in the div such as a space it won't render without content.
<table height="100%">
<td width="60px" valign="top" align="center" >
<div class="PageLine2V"> </div>
</td>
</table>
Setting height to 100% requires that the parent have an explicitly defined height. Add height: 100% to the td (the parent of the div). Tested and working with jsfiddle.
.PageLine2V
{
width:2px;
content: "";
min-height: 100%;
background-color:#D1C094;
background-image:url('../images/gold-line-2v.gif');
background-repeat:repeat-y;
height: 35px; /* As required */
display:inline-block;
}
Hope this will work. As I tried, I've used the same code with a fixed height in pixels and added display:inline-block;. Next you may try adjusting the parent height parameters for further positioning.
give it a position:absolute;
http://jsfiddle.net/eg6DP/
you can see it on the far left,and while you're at it give the table a position as well.
I have the following code:
<td style="position: relative; min-height: 60px; vertical-align: top;">
Contents of table cell, variable height, could be more than 60px;
<div style="position: absolute; bottom: 0px;">
Notice
</div>
</td>
This does not work at all. For some reason, the position:relative command isn't being read on the TD and the notice DIV is being placed outside of the content container at the bottom of my page. I have tried to put all the contents of the TD into a DIV such as:
<td>
<div style="position: relative; min-height: 60px; vertical-align: top;">
Contents of table cell, variable height, could be more than 60px;
<div style="position: absolute; bottom: 0px;">
Notice
</div>
</div>
</td>
However, this creates a new problem. Since the height of the contents of the table cell is variable, the notice DIV isn't always at the bottom of the cell. If a table cell stretches beyond the 60px marker, but none of the other cells do, then in the other cells, the notice DIV is at 60px down, instead of at the bottom.
This is because according to CSS 2.1, the effect of position: relative on table elements is undefined. Illustrative of this, position: relative has the desired effect on Chrome 13, but not on Firefox 4. Your solution here is to add a div around your content and put the position: relative on that div instead of the td. The following illustrates the results you get with the position: relative (1) on a div good), (2) on a td(no good), and finally (3) on a div inside a td (good again).
<table>
<tr>
<td>
<div style="position:relative;">
<span style="position:absolute; left:150px;">
Absolute span
</span>
Relative div
</div>
</td>
</tr>
</table>
This trick also suitable, but in this case align properties (middle, bottom etc.) won't be working.
<td style="display: block; position: relative;">
</td>
Contents of table cell, variable height, could be more than 60px;
<div style="position: absolute; bottom: 0px;">
Notice
</div>
With regards to your second attempt, did you try using vertical align ?
Either
<td valign="bottom">
or with css
vertical-align:bottom
also works if you do a "display: block;" on the td, destroying the td identity, but works!