Can you explain why these two HTML codes result in different look when rendered? fiddle1 and fiddle2
The only difference in the code is that in fiddle1 style="width: 50px;" is in the first row of the table, while in fiddle2 it is in the second row. But this results in different widths for each one.
According to Chrome Dev Tools fiddle1 both cells/columns have 51px width (should be 50px anyways), and in fiddle2 the first cells/columns have 49px width and the second 50px width.
Markup in Fiddle 1
<table>
<tr>
<td style="width: 50px;">Test</td>
<td style="width: 50px;">Testing 1123455</td>
</tr>
<tr>
<td>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</td>
<td>B</td>
</tr>
</table>
Markup in Fiddle 2
<table>
<tr>
<td>Test</td>
<td>Testing 1123455</td>
</tr>
<tr>
<td style="width: 50px;">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</td>
<td style="width: 50px;">B</td>
</tr>
</table>
CSS for both fiddles
table {
table-layout: fixed;
width: 100px;
}
td {
border: 1px solid black;
overflow: hidden;
}
That is the magic of 'table-layout: fixed'.
As specified in this link
The table-layout CSS property specifies the algorithm used to lay out cells, rows, and columns.
When the value is 'fixed': Table and column widths are set by the widths of table and col elements or by the width of the first row of cells. Cells in subsequent rows do not affect column widths.
In your first case: As you specified the width for columns of first row. Rendering algorithm takes the width and renders it with that width. The extra 1px you see, is just the border width.
In Second Case: As there is no width for first row specified. It takes the table width and try to adjust the row columns in it. As for two columns there will be three borders, we left with the 97px to be divided among the two columns. As pixel cannot be divided into decimals, you get 48px and 49px width of columns. extra 1px is for the border width
I am using the trick of assigning a small width to a table cell for it to wrap its content so the following works fine (I want the second and third cell to be assigned their width automatically according to their content):
<table style="width:100%;">
<tr>
<td style="width:1px;">11111111</td>
<td>1111111111111111</td>
<td>11111111</td>
<td style="width:1px;">11111111</td>
</tr>
</table>
But in my project, I am going to animate the width of the cell content to zero so I want the cell to be also of "0" width because I have a hover styling on the cell and even 1 px will trigger this styling when the mouse hovers over it. But assigning the cells 0 width instead of 1px is totally ignored.
One solution I thought of was binding the hover styling to the div inside the td. But is there a way to make the cell width really "0"?
try to use table-layout:fixed and width:0px on the td
<table style="width:100%;table-layout: fixed;">
<tr>
<td style="width: 0px;"> </td>
<td>1111111111111111</td>
<td>11111111</td>
<td style="width: 0px;"></td>
</tr>
</table>
According to the CSS spec, when a table has the table-layout:fixed property, its width is calculated like this:
...the width of each column is determined as follows:
A column element with a value other than 'auto' for the 'width' property sets the width for that column.
Otherwise, a cell in the first row with a value other than 'auto' for the 'width' property determines the width for that column. If the cell spans more than one column, the width is divided over the columns.
Any remaining columns equally divide the remaining horizontal table space (minus borders or cell spacing).
The width of the table is then the greater of the value of the 'width' property for the table element and the sum of the column widths (plus cell spacing or borders).
My understanding of this is:
the width of each column is calculated (with the width property of <col> elements, if present, taking precedence)
the column widths are totalled
if the column width total is greater than the width property of the <table> element, then the table will be as wide as the column width total.
However — in the following example, I have a table with one row containing three cells. Each column’s width is set to 100 pixels using the <col> element. The table element has no width assigned to it, and it’s the child of a <div> that’s 200 pixels wide.
I’d expect the width of the table to be 300 pixels, and for it to therefore overflow its parent <div>. However, instead, the table is only 200 pixels wide (i.e. as wide as its parent <div>), and each column is therefore narrowed to 66.6 pixels wide. (I’ve checked in the latest Safari, Chrome, Firefox, and Edge.)
Why is the table only 200 pixels wide, and not 300 pixels?
<div style="background:black; color:white; width:300px;">300px</div>
<br>
<div style="background:black; color:white; width:200px;">200px</div>
<br>
<div style="width:200px; background:green; overflow:scroll;">
<table style="table-layout:fixed; border-collapse:collapse;">
<col style="width:100px;">
<col style="width:100px;">
<col style="width:100px;">
<tr>
<td>1</td>
<td>2</td>
<td style="background:red;">3</td>
</tr>
</table>
</div>
(I’ve given the <div> a green background and overflow:hidden, and the third cell a red background, to make the unexpected result clearer.)
You are correct on you interpretation of the rules. The problem is that the width of the table is not set, so the browser can't compare with the column width sum. Just set the width for the table, even width: 0px will work.
<div style="background:black; color:white; width:300px;">300px</div>
<br>
<div style="background:black; color:white; width:200px;">200px</div>
<br>
<div style="width:200px; background:green; overflow:scroll;">
<table style="table-layout:fixed; border-collapse:collapse;width:0px">
<col style="width:100px;">
<col style="width:100px;">
<col style="width:100px;">
<tr>
<td>1</td>
<td>2</td>
<td style="background:red;">3</td>
</tr>
</table>
</div>
I want to change the size of my table cell to be smaller in height. The first cell has an image of 300px width. I'd like the second cell to have a height of 100px. I've tried html solutions like <td height="10"> but that hasn't worked. What I'm looking to do is have an image on the left and a text block on the right.
<table>
<tr>
<td> <img id="plattOverlook" src="images/Scenic/plattOverlook.jpg"/> </td>
<td style="background: white"> This is an overlook. </td>
</tr>
</table>
In a simple table adjacent table data cells will always be the same height unless you use
rowspan=*
Have a look at this page (about half way down) -
http://www.htmlcodetutorial.com/tables/_TD_COLSPAN.html
You will have to use rowspan for the image.
Other wise I don't think there's any possible solution
Use rowspan.
Check this fiddle:
http://jsfiddle.net/10z7ya28/
td {
width: 100px;
height: 50px;
}
I have a page layout that is based on tables, and as much as I would like to restructure it with more modern markup, that is not an option. The layout uses a cell that spans two rows as a sidebar on the right side, while the upper left cell contains a simple header, and the lower left cell contains the main content of the page. The top left cell has a fixed height, and the height of the bottom cell and right cell is not specified. I have created a simplified example that illustrates my problem:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style type="text/css">
.fixed { height: 100px; }
table { border: 1px solid #000; }
td { border: 1px solid #ddd; vertical-align: top; }
tr { border: 1px solid #cfc; }
* { padding: 15px; }
</style>
</head>
<body>
<table>
<tr class="fixed">
<td>left</td><td rowspan="2"><div style="height: 500px;">right</div></td>
</tr>
<tr class="stretch">
<td>left</td>
</tr>
<tr class="footer">
<td colspan="2">footer</td>
</tr>
</table>
</body>
</html>
I have set the height of the right column inline at 500px to simulate content that is taller than the height of the two left columns. This behaves as expected in modern browsers: The height of the top left cell remains fixed, and the lower cell stretches to fill the extra space. But in IE8, both left cells are stretched vertically. I need the top cell to keep its fixed height. How do I get IE8 to honor the height specified for the top left cell using only CSS?
Edit:
Instead of setting the height on the right column td, I am setting the height on a div inside the right column.
I think Jeroen is right that there are no pure CSS solutions to this problem. Any time there are cells in a table with rowspan set, IE is going to ignore any explicit heights set on those rows. The solution is to never use rowspan. In my situation I was able to circumvent the problem by placing the content that was spanning two rows in the second row, leaving the cell in the first row empty, and using a negative margin to move the start of the content up into the first row. I hope this is helpful to somebody else. If anybody does have a pure CSS solution I'll accept that as the answer.
Interesting problem. Afraid the answer may be that there are no real solutions to the problem you describe, only workarounds. I found that adding some style to the second "left" td made the problem disappear, at least in your sample:
<td style="min-height: 500px;">left</td>
Hope that helps.
PS. IE9 had the same problem.
Even if a cell only contains an image, you must know that table cells have their height computed according to the position of the text baseline; and the current style of text has an impact on computing this baseline position and the line-spacing after it.
You may think that setting "line-height:1" would be enough to avoid this line-spacing, i.e. the margin gap that always occurs below every line of text. This is not enough. The simplest solution is to set "line-height:0.8" (or lower) for the cell containing the image, so that the 0.2em default added gap below the baseline (which is still infered as default due to the absence of text) will make the baseline fit in the cell height. Then you can properly place an image (or any fixed height element) in the cell whose height will determine the cell height, without having the cell height stretched.
Note: with this line-height, any text you would place in that cell would have its baseline just at the bottom of the cell, so that descenders will overlap the bottom padding, border, border-spacing of the current cell, or in the border, padding or content of the cell in the next row, or contents below the table if the cell was on the last row.
Tested on Google Chrome (current version 15)
Example (HTML5):
<!DOCTYPE html>
<html><head>
<title>Examples of image transforms (rotations and mirroring)</title>
<style>
table,tbody,tr,td,image{margin:0;border:1px solid #999;border-collapse:collapse;border-spacing:0;background:#FFF;color:#000;padding:0;vertical-align:middle;text-align:center;}
td.z{line-height:0;}
</style>
</head><body>
<table border="0" cellspacing="0" cellpadding="0">
<tbody><tr>
<td style="border-bottom:hidden">Normal 0° (1,0,0,1,0,0)</td>
<td style="border-bottom:hidden">Mirrored 0° (-1,0,0,1,0,0)</td>
<td style="border-bottom:hidden">Mirrored 90° (0,1,1,0,0,0)</td>
<td style="border-bottom:hidden">Normal −90° (0,1,-1,0,0,0)</td>
</tr><tr>
<td class="z"><image alt="" src="Avatar-220px.jpg" style="-webkit-transform:matrix(1,0,0,1,0,0);"/></td>
<td class="z"><image alt="" src="Avatar-220px.jpg" style="-webkit-transform:matrix(-1,0,0,1,0,0);"/></td>
<td class="z"><image alt="" src="Avatar-220px.jpg" style="-webkit-transform:matrix(0,1,1,0,0,0);"/></td>
<td class="z"><image alt="" src="Avatar-220px.jpg" style="-webkit-transform:matrix(0,1,-1,0,0,0);"/></td>
</tr><tr>
<td class="z"><image alt="" src="Avatar-220px.jpg" style="-webkit-transform:matrix(1,0,0,-1,0,0);"/></td>
<td class="z"><image alt="" src="Avatar-220px.jpg" style="-webkit-transform:matrix(-1,0,0,-1,0,0);"/></td>
<td class="z"><image alt="" src="Avatar-220px.jpg" style="-webkit-transform:matrix(0,-1,1,0,0,0);"/></td>
<td class="z"><image alt="" src="Avatar-220px.jpg" style="-webkit-transform:matrix(0,-1,-1,0,0,0);"/></td>
</tr><tr>
<td style="border-top:hidden">Mirrored 180° (1,0,0,-1,0,0)</td>
<td style="border-top:hidden">Normal 180° (-1,0,0,-1,0,0)</td>
<td style="border-top:hidden">Normal 90° (0,-1,1,0,0,0)</td>
<td style="border-top:hidden">Mirrored −90° (0,-1,-1,0,0,0)</td>
</tr></tbody>
</table>
</body></html>
Note the trick on class "z" for table cells (line-height:0) containing only an image, in order to make them fit exactly the image size.
The images shown in this example is a small square photo in 8 different orientations. There's only a thin 1px gray border enclosing each photo and its label displayed above or below, the photos are fitting exactly within the cell borders.
Note that the reorientation uses WebKit styles (for Safari and Chrome); you can add the equivalent properties for IE and Firefox by changing the prefix; for CSS3, no prefix will be needed. If not these transforms are not supported, the images will not be reoriented/mirrored, but they will still fit exactly the cell, without extra internal gaps.