I have a table with a known width, 776 pixels, and three columns. The third column has a known width, 216 pixels, but the other two do not have known widths. The behavior I want is for the second column to have the same width as its child element. Whatever width is left over, 776 - 216 - 2nd, would be the width for the first column.
I found an example that sets the width of the column that should have its width minimized to 1 pixel. This does seem to work, but it seems like it is a hack and I don't understand why it works. Is there a more "standard" way to achieve the same result?
Here is my HTML with inline CSS as an example:
<table style="width:776px; height:48px;">
<tr>
<td style="height:48px;">
<!-- Note: Setting font size to zero prevents white space from contributing to an inline block element's width -->
<div style="background:#f0f0f0; border:solid 2px #808080; font-size:0; margin-left:8px; text-align:center;">
<h3 style="display:inline-block; font-size:20px; line-height:28px; padding:8px;">Art</h3>
<h3 style="display:inline-block; font-size:20px; line-height:28px; padding:8px;">Events</h3>
<h3 style="display:inline-block; font-size:20px; line-height:28px; padding:8px;">Papers</h3>
<h3 style="display:inline-block; font-size:20px; line-height:28px; padding:8px;">Research</h3>
</div>
</td>
<!-- Note: Setting width to one pixel removes horizontal spacing -->
<td style="vertical-align:middle; width:1px; height:48px;">
<h3 style="margin-left:8px;"><label for="search">Search:</label></h3>
</td>
<td style="vertical-align:middle; width:216px; height:48px;">
<input id="search" style="margin-left:8px; width:208px;" type="text" value="" maxlength="32">
</td>
</tr>
</table>
Well, an easy way would be to set the 1st cell to width: 100%. That would force it to fill as much as it can the parent table's width. Then, to the third cell, you put a 216px content element (like a div).
The table's cell always try to respect its content. So this way, the 2nd div would be squized in the middle, just respecting its own content. The 3rd one would respect its 216px content, and the 1st would fill up the rest.
Working JsFiddleExample
<table>
<tr>
<td>1stContent</td> <!-- Fills what it can -->
<td>2ndContent</td> <!-- Squized in the middle -->
<td>
<!-- Will respect the width of its content -->
<div class="dv3rd">
216px
</div>
</td>
</tr>
</table>
CSS:
table {
width: 776px;
background: silver;
}
td:nth-child(1) {
width: 100%;
background: red;
}
td:nth-child(2) {
background: green;
}
td:nth-child(3) {
background: blue;
}
.dv3rd {
width: 216px;
}
However
As well commented, you should not be using tables for the page layout. A simple replacement would be working with css tables, where your divs can act like display: table and display: table-cell elements.
Here's the same example, but using div's instead:
Working JsFiddleExample - Tableless
<div class="table">
<div>
1stContent
</div>
<div>
2ndContent
</div>
<div>
<div class="dv3rd">
216px
</div>
</div>
</div>
CSS:
.table {
width: 776px;
background: silver;
display: table;
}
.table > div:nth-child(1) {
display: table-cell;
width: 100%;
background: red;
}
.table > div:nth-child(2) {
display: table-cell;
background: green;
}
.table > div:nth-child(3) {
display: table-cell;
background: blue;
}
.dv3rd {
width: 216px;
}
I found the reason why this work's in BoltClocks link (in the comments): http://www.w3.org/TR/CSS21/tables.html#auto-table-layout
...This algorithm may be inefficient since it requires the user agent
to have access to all the content in the table before determining the
final layout and may demand more than one pass.
Column widths are determined as follows:
Calculate the minimum content width (MCW) of each cell: the formatted content may span any number of lines but may not overflow the cell box. If the specified 'width' (W) of the cell is greater than MCW, W is the minimum cell width. A value of 'auto' means that MCW is the minimum cell width...
Answer:
Calculate the minimum content width (MCW) of each cell: the formatted content ... may not overflow the cell box.
Related
I tried to create a box with rotating content, simply using an outer box with a specified width and overflow: hidden, and inner boxes with display: inline-block; width: 100%. Everything worked as expected, until I added an image to each of the three "content boxes". Even though the images were narrow enough to fit well within the available space, the outer box' parent element now started overflowing its parent, in turn making the rotating box wider (since it had a relative width). The problem was the same in FF (28) and IE (11), but things were fine in Chrome.
In the end I boiled it down to this being a table layout issue, since adding table-layout: fixed on a table ancestor stopped the td parent of the rotating box to grow unneccessarily. (There are tables used for layout due to legacy reasons.)
What I wonder now is why this is happening, and if there is something wrong with my approach for the boxes. I've created a minimal example of the problem below (fiddle at http://jsfiddle.net/rvy2V/9/).
(In the example I use overflow: visible instead of hidden to make it easier to see what is going on. I also have whitespace between the inline blocks, which is bad for layout but good for clarity.)
HTML
<div id="wrapper">
wrapper
<table>
<tbody>
<tr>
<td id="cell">
table cell
<div class="niceBox slidePanes" id="outerBox">
<span class="slidePane">
.slidePane
<div class="body">
<div class="inner">inner box</div>
</div>
</span>
<span class="slidePane">
.slidePane
<div class="body">
<div class="inner">inner box</div>
</div>
</span>
<span class="slidePane">
.slidePane
<div class="body">
<div class="inner">inner box</div>
</div>
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
CSS
.niceBox {
border: 1px solid #d7d7d7;
background-color: #f6f6f6;
}
.slidePanes {
overflow: visible;
white-space: nowrap;
}
.slidePanes .slidePane {
display: inline-block;
width: 100%;
white-space: normal;
vertical-align: top;
background-color: #bbf;
padding: 5px 0;
}
#wrapper {
width: 525px;
background-color: #888;
}
#cell {
background-color: #bbb;
}
#outerBox {
width: 50%;
}
div.inner {
width: 230px;
background-color: #f88;
}
Note in the fiddle how the table cell (medium gray) is wider than the wrapper (dark gray), but still not wide enough to contain all three content boxes (purple). Also note how, as a result, the rotating box (yellow border) is wider than the intended 50% of the wrapper. Also note how the inner boxes (red), which should be the widest thing in each content box, is not determining the width of each box.
I have a simple table with 1 TD with vertical-align:middle;. This TD contains an Image :
table
{
border:solid 1px red;
width:300px;
}
td
{
height:100px;
vertical-align:middle;
width:100%;
border:solid 1px green;
}
img
{
height:43px;width:43px;
}
span
{
vertical-align:middle;
}
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8/>
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td>
<img src='http://static.jsbin.com/images/favicon.png'/>
</td>
</tr>
</table>
</body>
</html>
Everything is Ok and the IMG is vertical-aligned.
But If I add another elements after that Image ( a span for example ) :
table
{
border:solid 1px red;
width:300px;
}
td
{
height:100px;
vertical-align:middle;
width:100%;
border:solid 1px green;
}
img
{
height:43px;width:43px;
}
span
{
vertical-align:middle;
}
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8/>
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td>
<img src='http://static.jsbin.com/images/favicon.png'/>
<span>aaa</span>
</td>
</tr>
</table>
</body>
</html>
Question
Doesn't the vertical align of the TD should vertical align all its childs ?
How can I make the span to be centered as well ?
NB
I don't want to add another TD , nor using float with padding/margin. IE8+.
edit:
Desired result :
Question
Doesn't the vertical align of the TD should vertical align all its childs ?
NO.
When you apply vertical-align to td, it is only applied to td, and is not inherited by any of its children.
If i have a TD with only span in it - it will vertical align. If I had a TD with only IMG inside it - it will also align.
This is because of the way vertical-align for td works. The total height of the cell i.e td is calculated and the whole cell is aligned vertically.
If there is a single img, then the height of td is same as that of img, so it seems that vertical-align for img is also middle. But actually, the td is vertically aligned to the middle with the img as vertical-align : baseline
Same is the case when there is a single span.
but if i have both - it doesn't. why is that ?
Because now, the height of td is the combined height of both img + span. So, actually, td is vertically aligned in the middle, but not img and span.
How can I make the span to be centered as well ?
You need to apply this CSS :
td > * {
vertical-align : middle;
}
This will apply the CSS to all the children.
Check the JSFiddle for a better picture.
Hope, this answers your question.
You can just use vertical-align: middle; to your span
img
{
height:43px;width:43px;
display: inline;
vertical-align: middle;
}
span
{
vertical-align:middle;
display: inline;
}
your jsbin
As per comment
You may think as if td is given vertical-align: middle; then it should align all the contents inside this but having an image and a span in which browser is understanding the image is what? : is this inline or inline-block, so you need to set display: inline or inline-block; Then you may see its working only applying display property for image. demo
Edit
img tag : source: display inline vs inline-block
They are "block" elements in that they have a width and a height.
It's true, they are both - or more precisely, they are "inline block" elements. This means that they flow inline like text, but also have a width and height like block elements.
Also check this:
Replaced Elements
A replaced element is any element whose appearance and dimensions are defined by an external resource. Examples include images ( tags), plugins ( tags), and form elements (, , , and tags). All other elements types can be referred to as non-replaced elements.
Replaced elements can have intrinsic dimensions—width and height values that are defined by the element itself, rather than by its surroundings in the document. For example, if an image element has a width set to auto, the width of the linked image file will be used. Intrinsic dimensions also define an intrinsic ratio that’s used to determine the computed dimensions of the element should only one dimension be specified. For example, if only the width is specified for an image element—at, say, 100px—and the actual image is 200 pixels wide and 100 pixels high, the height of the element will be scaled by the same amount, to 50px.
Replaced elements can also have visual formatting requirements imposed by the element, outside of the control of CSS; for example, the user interface controls rendered for form elements.
In an inline formatting context, you can also think of a replaced element as being one that acts as a single, big character for the purposes of wrapping and layout. A width and height can be specified for replaced inline elements, in which case the height of the line box in which the element is positioned is made tall enough to accommodate the replaced element, including any specified box properties.
Here's a JS fiddle solution
fiddle
Here's the css
table
{
border:solid 1px red;
width:300px;
}
td
{
height:100px;
vertical-align:middle;
width:100%;
border:solid 1px green;
}
img
{
display: inline;
height: 43px;
width: 43px;
position: relative !important;
float: left;
}
span
{
height: auto !important;
width: 80%;
float: right;
position: relative;
vertical-align: middle !important;
text-align: left;
}
In all the cases, the vertical-align: middle; on the td does what is expected of it. That is, align the td to the center of that row and the entire contents of the td to the vertical middle (by default) leaving equal spaces at the top and the bottom.
Here is what the W3 Spec says about vertical-align: middle:
The center of the cell is aligned with the center of the rows it spans.
Row height calculation:
The height of a 'table-row' element's box is calculated once the user agent has all the cells in the row available: it is the maximum of the row's computed 'height', the computed 'height' of each cell in the row, and the minimum height (MIN) required by the cells.
In CSS 2.1, the height of a cell box is the minimum height required by the content. The table cell's 'height' property can influence the height of the row (see above), but it does not increase the height of the cell box.
Cell boxes that are smaller than the height of the row receive extra top or bottom padding.
As a result of the above, the height of the tr and the td becomes 100px but the cell box takes up only the amount of height required by the contents (img height = 43px). Now since the Cell box is smaller than the row height, extra padding is added like shown in Box 5 of the image above and thus makes the contents also get aligned to the middle.
TD has only image:
When there is only an img, the content height is equal to the height of the img. So it gets positioned to the middle.
As can be seen in the above image, this does not require a vertical-align: middle on the img explicitly because the td aligns its contents to the middle.
TD has only inline data:
When the td has only a span or span plus an inline div, the height of the content is equal to the default line-height for text (or any specified line-height). In this case also, the td aligns it correctly.
When the text content goes beyond the first line (refer to the demo), you can see that the td automatically pushes the first-line (marked in cyan background) upwards to ensure that the contents on the whole is aligned to the middle (not just a single line).
TD has an image and a span:
When we put an img and a span (inline text) within the td, the content height becomes equal to the height of the img plus the line-height of the second and subsequent lines.
In this situation, there are two possible cases as described below:
Case 1 - img tag has no vertical-align specified
In this case, the img is aligned to the baseline (default). Then the td aligns the entire content to the middle. This means the td leaves around 28.5px (= (100-43)/2) gap at the top and the bottom of the content. Again, the vertical-align on td does the job, it puts the contents in the middle (that is, leave equal gap on top and bottom). But the text gets pushed down because img height is more.
If we reduce the img height to less than the line height (say 10px), we can see that even with img + span it gets aligned to the middle.
Case 2 - img tag has vertical-align: middle
In this case also vertical-align on the td does the same as what it did for Case 1. However, the text in this case is near the middle because the img is also aligned to the middle of the line.
table {
border: solid 1px red;
}
td {
height: 100px;
width: 200px;
vertical-align: middle;
border: solid 1px green;
}
img {
height: 43px;
width: 43px;
border: solid 1px green;
}
.one td + td img {
vertical-align: middle;
}
.three td + td img {
height: 10px;
width: 10px;
}
.four img {
vertical-align: middle;
}
.five img + img{
height: 50px;
width: 50px;
}
td:first-line {
background-color: cyan;
}
div {
display: inline;
}
<table>
<tr class='one'>
<td>
<img src='http://static.jsbin.com/images/favicon.png' />
</td>
<td>
<img src='http://static.jsbin.com/images/favicon.png' />
</td>
</tr>
<tr class='two'>
<td>
<div>aaa</div>
<span>aaa</span>
</td>
<td>
<div>aaa</div>
<span>aaa aaaaaaa aaaaaaaa aaaaaaaa</span>
</td>
</tr>
<tr class='three'>
<td>
Case 1
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span</span>
</td>
<td>
Case 1
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span</span>
</td>
</tr>
<tr class='four'>
<td>
Case 2
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span</span>
</td>
<td>
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span + more text.......</span>
</td>
</tr>
<tr class='five'>
<td>
Case 3
<img src='http://static.jsbin.com/images/favicon.png' />
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span text...</span>
</td>
<td>
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span + more text.......</span>
</td>
</tr>
</table>
Just add vertical-align:middle; to your img style?
Demo
<style>
table
{
border:solid 1px red;
width:300px;
}
td
{
height:100px;
width:100%;
border:solid 1px green;
vertical-align:middle;
line-height:100px;
}
img
{
height:43px;width:43px;
vertical-align:middle;
}
</style>
DEMO
just add this class:
td *{
vertical-align:middle
}
Edit:
question is why when you add a pic to the td text goes bottom of pic and not any more middle of td.
this is my answer:
when you set td vertical-align to middle it should not set all content vertical-align to middle, they are still baseline. and when you add a pic to the text, the line height rise to the height of image and text is bottom of this height, so you need to set vertical-align to middle for fix this problem.
here you can see what i said: DEMO
and sorry about my bad english
Is this what you mean? http://jsfiddle.net/JFVNq/
The reason is spans are treated as inline so you need to make them block.
CSS for the span:
td.vert span
{
vertical-align: middle;
display: block;
}
I think we are all nearly there but
td img,
td span {
display:inline-block;
vertical-align:middle;
}
seems to work.
Codepen Example
Or am I missing something?
This CSS attribute doesn't go on any other kinds of elements. When the novice developer applies vertical-align to normal block elements (like a standard ) most browsers set the value to inherit to all inline children of that element.
You simply need to add vertical-align: middle to the <img> class.
Your CSS should look like this...
table
{
border:solid 1px red;
width:300px;
}
td
{
height:100px;
vertical-align:middle;
width:100%;
border:solid 1px green;
}
img
{
height:43px;width:43px;
vertical-align: middle;
}
You can view the Sample Fiddle...
Just move your vertical-align: middle from the span to the image.
The image will align itself on the text; works better than the opposite ;)
img
{
height:43px;width:43px;
vertical-align:middle;
}
http://jsfiddle.net/ZnpNF/1/
I am trying to find a simple way to create a 1 row, 3 column table using css. I want the table width to be the width of the container div, and the height to be just 1 line. The first and third column should expand to contain the width of the text. The middle column should fill any remaining width (up to the container width), with overflow hidden.
I am having trouble with the middle column. When I use white-space:nowrap and overflow:hidden it extends the table beyond the width of the container div.
<div style="width:500px;">
<table style="width:100%;">
<tr>
<td style="white-space:nowrap;">
Title is Here
</td>
<td style="">
When this is too long to display on one line the overflow is hidden
</td>
<td style="white-space:nowrap;">
Last updated 12:05pm
</td>
</tr>
</table>
</div>
or is there maybe an easier way using div? but I can't seen to figure out how to make the center div only fill the space available instead of moving to the next line.
<div style="width:500px;">
<div style="float:left;">
Title is Here
</div>
<div style="float:left;">
When this is too long to display on one line the overflow is hidden
</div>
<div style="float:right;">
Last updated 12:05pm
</div>
</div>
you could do it with div based layout too
css
.table{width: 100%; }
.table, .table .item{ height: 20px; overflow: hidden;}
.table .item{float: left; box-sizing: border-box; -moz-box-sizing: border-box; background: #fcc; text-align: center;}
.table .item.right{float: right;}
.table .center{float: none; background: #ccf; }
markup
<div class="table">
<div class="item left">left content</div>
<div class="item right">right content</div>
<div class="center item">some center content</div>
</div>
your middle td doesn't have any width or height specified. Therefore, it has default width:auto and height:auto. That's why, it always scales itself up. If you try to give your td a fixed width, it will scale vertically.
You can stop this by giving it a fixed height and width along with display:inline-block;
same goes for divs also. but in case of divs, you don't need to specify display:inline-block;
you need to give your td (first sample ) or div(second sample) a fixed width and height, to hide the overflow i.e. to make overflow:hidden; work.
table based layout:
try this css in your middle td : see this fiddle
.middle
{
height:20px;
width:70%;
overflow:hidden;
display:inline-block; /*add this property also for the td */
}
div based layout
give your div this css: see this fiddle
.middle
{
float:left;
width:40%;
height:20px;
overflow:hidden;
}
Given the following example: http://jsfiddle.net/upsidown/z4m7r/
HTML:
<table class="main-table" cellspacing="20">
<tr>
<td style="height:100%;"><table class="sub-table"><tr><td>Some text</td></tr><tr><td class="bottom-align">Some bottom aligned element</td></tr></table></td>
<td>Some very long text. Some very long text. Some very long text. Some very long text. Some very long text. Some very long text. </td>
<td>Some other text</td>
</tr>
</table>
CSS:
.main-table {
width:300px;
vertical-align: top;
}
.main-table td {
vertical-align: top;
}
.sub-table {
height:100%;
}
td {
border:2px solid black;
}
td.bottom-align {
vertical-align: bottom;
background:yellow;
}
The yellow cell text should be vertically aligned at the bottom. This works on Firefox but not on Safari / Chrome (webkit) browsers.
Any idea how I can achieve that? Thanks in advance.
First off: Why are you using tables and nested tables at that? Is this really for tabluar data?
To your problem: Webkit most likely abides strictly by the CSS rules for height, which says, that height in per cent only applies if the containing block has an explicit height.
That means that you need to give the main-table a height (the height of a cell/row is explicitly calculated from the height of the table and the other cells/rows in the table). And if that is in turn in per cent, then also the next parent (here body), and so forth.
So either something like
.main-table { height: 500px; }
or
html, body, .main-table { height: 100%; }
will help.
(BTW, the height: 100% on the cell makes no sense.)
A simple solution is to fill the space with padding:
td.bottom-align {
padding-top:100%;
vertical-align: bottom;
background:yellow;
}
Here's the demo: http://jsfiddle.net/z4m7r/11/
--EDIT--
Set the parent table at 100% height and it should do the trick. Demo: http://jsfiddle.net/z4m7r/9/
I've updated your jsfiddle: http://jsfiddle.net/z4m7r/6/
To start with, I wouldn't use a table inside of another table as it will make the markup a nightmare to read and maintain. It's also difficult to put one row at the bottom of the table and the other at the bottom. Instead I just put two divs inside the cell:
<td class="firstcell" style="height:200px;">
<div>Some text</div>
<div class="bottom">Some bottom aligned text</div>
</td>
Next, I set the position of the parent cell to relative, and made the bottom div absolute:
.firstcell {
position: relative;
width: 100px;
}
.firstcell > div {
border: solid thin black;
}
.bottom {
position: absolute;
bottom: 0;
background: yellow;
}
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;
}