How do I make a div fill an entire table cell? - html

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>

Related

Setting a table's td height not working in Firefox

I've got a table with the contents of the cells completely filling them. I gave the content a fixed width and a height of 100% so that elements that get bigger are still able to grow the cells. The cells also have a minimum height via the simple height attribute so the 100% height of the content has an effect. In Chrome and Edge everything works fine, but in Firefox the cells don't grow:
Chrome:
Firefox:
If you want to try yourself:
table {
border-spacing: 8px;
font-size: 14px;
}
td {
height: 50px;
}
td div {
height: 100%;
width: 200px;
background-color: green;
}
<table>
<tr>
<td>
<div>
This div is normal sized.
</div>
</td>
<td>
<div>
This div is normal sized.
</div>
</td>
</tr>
<tr>
<td>
<div>
This div is also normal sized but should size accordingly.
</div>
</td>
<td>
<div>
This div is very very big so it gets higher and should affect other divs in the same row. But not in Firefox apparently.
</div>
</td>
</tr>
</table>
Not sure if this a bug in Firefox or a feature in Chrome, but the way I understood table sizing is that table elements cannot have a fixed size. Instead their width and height attributes are used as a min-width / min-height and they grow according to their content. Is there a quick workaround or should I rebuild the table in flexbox layout?
Update
By the way, when I instead set a fixed height on the row / tr and height: 100%; on the td, it works in Firefox. But then it's broken in Chrome...
I managed to find a workaround. I added the lines
#-moz-document url-prefix() {
tr {
height: 50px; // Your min height
}
td {
height: auto;
}
}
to my css and now it seems to display correctly in firefox and chrome. Not very clean but it works.
Apparently Chrome was to adopt Firefox behaviour with tables in Version 50 but reverted because it broke too many layouts. The trick applying height: 100%; to the tds worked because all percent sizes are automatically translated to auto. Makes much more sense then.

Overflow scrollbar not showing on 100% height div in Firefox

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.

CSS table-cell equal width

I have an indeterminate number of table-cell elements inside a table container.
<div style="display:table;">
<div style="display:table-cell;"></div>
<div style="display:table-cell;"></div>
</div>
Is there a pure CSS way to get the table-cells to be equal width even if they have differently sized content within them?
Having a max-width would entail knowing how many cells you have I think?
Here is a working fiddle with indeterminate number of cells: http://jsfiddle.net/r9yrM/1/
You can fix a width to each parent div (the table), otherwise it'll be 100% as usual.
The trick is to use table-layout: fixed; and some width on each cell to trigger it, here 2%. That will trigger the other table algorightm, the one where browsers try very hard to respect the dimensions indicated.
Please test with Chrome (and IE8- if needed). It's OK with a recent Safari but I can't remember the compatibility of this trick with them.
CSS (relevant instructions):
div {
display: table;
width: 250px;
table-layout: fixed;
}
div > div {
display: table-cell;
width: 2%; /* or 100% according to OP comment. See edit about Safari 6 below */
}
EDIT (2013): Beware of Safari 6 on OS X, it has table-layout: fixed; wrong (or maybe just different, very different from other browsers. I didn't proof-read CSS2.1 REC table layout ;) ). Be prepared to different results.
HTML
<div class="table">
<div class="table_cell">Cell-1</div>
<div class="table_cell">Cell-2 Cell-2 Cell-2 Cell-2Cell-2 Cell-2</div>
<div class="table_cell">Cell-3Cell-3 Cell-3Cell-3 Cell-3Cell-3</div>
<div class="table_cell">Cell-4Cell-4Cell-4 Cell-4Cell-4Cell-4 Cell-4Cell-4Cell-4Cell-4</div>
</div>​
CSS
.table{
display:table;
width:100%;
table-layout:fixed;
}
.table_cell{
display:table-cell;
width:100px;
border:solid black 1px;
}
DEMO.
Just using max-width: 0 in the display: table-cell element worked for me:
.table {
display: table;
width: 100%;
}
.table-cell {
display: table-cell;
max-width: 0px;
border: 1px solid gray;
}
<div class="table">
<div class="table-cell">short</div>
<div class="table-cell">loooooong</div>
<div class="table-cell">Veeeeeeery loooooong</div>
</div>
Replace
<div style="display:table;">
<div style="display:table-cell;"></div>
<div style="display:table-cell;"></div>
</div>
with
<table>
<tr><td>content cell1</td></tr>
<tr><td>content cell1</td></tr>
</table>
Look at all the issues surrounding trying to make divs perform like tables. They had to add table-xxx to mimic table layouts
Tables are supported and work very well in all browsers. Why ditch them? the fact that they had to mimic them is proof they did their job and well.
In my opinion use the best tool for the job and if you want tabulated data or something that resembles tabulated data tables just work.
Very Late reply I know but worth voicing.
this will work for everyone
<table border="your val" cellspacing="your val" cellpadding="your val" role="grid" style="width=100%; table-layout=fixed">
<!-- set the table td element roll attr to gridcell -->
<tr>
<td roll="gridcell"></td>
</tr>
</table>
This will also work for table data created by iteration
This can be done by setting table-cell style to width: auto, and content empty. The columns are now equal-wide, but holding no content.
To insert content to the cell, add an div with css:
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
You also need to add position: relative to the cells.
Now you can put the actual content into the div talked above.
https://jsfiddle.net/vensdvvb/
Here you go:
http://jsfiddle.net/damsarabi/gwAdA/
You cannot use width: 100px, because the display is table-cell. You can however use Max-width: 100px. then your box will never get bigger than 100px. but you need to add overflow:hidden to make sure the contect don't bleed to other cells. you can also add white-space: nowrap if you wish to keep the height from increasing.

Empty div with 2px width and background color doesnt show with height as 100%

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.

Setting max-height for table cell contents

I have a table which should always occupy a certain percentage of the height of the screen. Most of the rows are of fixed height, but I have one row that should stretch to fill the available space. In the event that the contents of a cell in that row overflows the desired height, I'll like the contents to clip using overflow:hidden.
Unfortunately, tables and rows do not respect the max-height property. (This is in the W3C spec). When there is too much text in the cell, the table gets taller, instead of sticking to the specified percentage.
I can get the table cell to behave if I specify a fixed height in pixels for it, but that defeats the purpose of having it automatically stretch to fill available space.
I've tried using divs, but can't seem to find the magic formula. If I use divs with display:table, :table-row, and :table-cell the divs act just like a table.
Any clues on how I can simulate a max-height property on a table?
<head>
<style>
table {
width: 50%;
height: 50%;
border-spacing: 0;
}
td {
border: 1px solid black;
}
.headfoot {
height: 20px;
}
#content {
overflow: hidden;
}
</style>
</head>
<body>
<table>
<tr class="headfoot"><td>header</td></tr>
<tr>
<td>
<div id="content">
put lots of text here
</div>
</td>
<tr>
<tr class="headfoot"><td>footer</td></tr>
</table>
</body>
Just put the labels in a div inside the TD and put the height and overflow.. like below.
<table>
<tr>
<td><div style="height:40px; overflow:hidden">Sample</div></td>
<td><div style="height:40px; overflow:hidden">Text</div></td>
<td><div style="height:40px; overflow:hidden">Here</div></td>
</tr>
</table>
We finally found an answer of sorts. First, the problem: the table always sizes itself around the content, rather than forcing the content to fit in the table. That limits your options.
We did it by setting the content div to display:none, letting the table size itself, and then in javascript setting the height and width of the content div to the inner height and width of the enclosing td tag. Show the content div. Repeat the process when the window is resized.
Possibly not cross browser but I managed get this: http://jsfiddle.net/QexkH/
basically it requires a fixed height header and footer. and it absolute positions the table.
table {
width: 50%;
height: 50%;
border-spacing: 0;
position:absolute;
}
td {
border: 1px solid black;
}
#content {
position:absolute;
width:100%;
left:0px;
top:20px;
bottom:20px;
overflow: hidden;
}
What I found !!!, In tables CSS td{height:60px;} works same as CSS td{min-height:60px;}
I know that situation when cells height looks bad . This javascript solution don't need overflow hidden.
For Limiting max-height of all cells or rows in table with Javascript:
This script is good for horizontal overflow tables.
This script increase the table width 300px each time (maximum 4000px) until rows shrinks to max-height(160px) , and you can also edit numbers as your need.
var i = 0, row, table = document.getElementsByTagName('table')[0], j = table.offsetWidth;
while (row = table.rows[i++]) {
while (row.offsetHeight > 160 && j < 4000) {
j += 300;
table.style.width = j + 'px';
}
}
Source: HTML Table Solution Max Height Limit For Rows Or Cells By Increasing Table Width, Javascript
I've solved just using this plugin: http://dotdotdot.frebsite.nl/
it automatically sets a max height to the target and adds three dots
I had the same problem with a table layout I was creating. I used Joseph Marikle's solution but made it work for FireFox as well, and added a table-row style for good measure. Pure CSS solution since using Javascript for this seems completely unnecessary and overkill.
html
<div class='wrapper'>
<div class='table'>
<div class='table-row'>
<div class='table-cell'>
content here
</div>
<div class='table-cell'>
<div class='cell-wrap'>
lots of content here
</div>
</div>
<div class='table-cell'>
content here
</div>
<div class='table-cell'>
content here
</div>
</div>
</div>
</div>
css
.wrapper {height: 200px;}
.table {position: relative; overflow: hidden; display: table; width: 100%; height: 50%;}
.table-row {display: table-row; height: 100%;}
.table-cell {position: relative; overflow: hidden; display: table-cell;}
.cell-wrap {position: absolute; overflow: hidden; top: 0; left: 0; width: 100%; height: 100%;}
You need a wrapper around the table if you want the table to respect a percentage height, otherwise you can just set a pixel height on the table element.
Another way around it that may/may not suit but surely the simplest:
td {
display: table-caption;
}