HTML table using colSpans not displaying as expected - html

I have an example of a simple HTML table that contains a number of div blocks.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head></head>
<body>
<table border=1 width="1000px" >
<tr><td></td><td></td><td></td><td></td></tr>
<tr valign="top"><td colspan="1" ><div style="width:180px;border: solid 1px black;">1</div></td><td colspan="3" ><div style="width:770px;border: solid 1px black;">2</div></td></tr>
<tr valign="top"><td colspan="4" ><div style="width:960px;border: solid 1px black;">3</div></td></tr>
<tr valign="top"><td colspan="2" ><div style="width:475px;border: solid 1px black;">4</div></td><td colspan="2" ><div style="width:475px;border: solid 1px black;">5</div></td></tr>
</table>
</body>
</html>
The problem is that the look of row 2 is not correct. The colspans are not behaving as expected. If I remove the fourth line then the second behaves correctly.
I am aware that divs and CSS is the way to go but for this application, at this time, this is not possible.

Your problem is auto table layout. It's hard for a browser to look at all the cells and work out how much width each is going to get from their content; it's double-hard when there are colspans (especially in this example where there's no way to tell how wide columns 3 and 4 should be at all); and it's triple-hard when you're poor old hard-of-thinking Internet Explorer, bless.
Don't make your browser struggle, wheeze and render slowly: use fixed table-layout and declare the width of every column exactly. Normally this would be done with <col> elements:
#thing { width: 950px; table-layout: fixed; border-spacing: 0; }
#thing .wide { width: 295px; }
#thing .narrow { width: 180px; }
#thing.box { border: solid black 1px; }
<table id="thing">
<col class="narrow" /><col class="wide" /><col class="wide" /><col class="narrow" />
<tr>
<td colspan="1"><div class="box">1</div></td>
<td colspan="3"><div class="box">2</div></td>
</tr>
<tr>
<td colspan="4"><div class="box">3</div></td>
</tr>
<tr>
<td colspan="2"><div class="box">4</div></td>
<td colspan="2"><div class="box">5</div></td>
</tr>
</table>
However there is a bug in Webkit that ignores <col> widths when there is no single unspanned cell in that column. This is quite unusual for tables, but it is the case in the above example: only the first column contains an unspanned cell. To work around it, you can either replace the <col> elements with a dud row at the start, styled to have minimal height:
#thing .cols td { height: 1px; line-height: 1px; font-size: 1px; }
<tr class="cols">
<td class="narrow"></td><td class="wide"></td><td class="wide"></td><td class="narrow"></td>
</tr>
Or, sometimes less intrusive, keep the <col>s and add a dud row at the bottom:
<tr class="cols"><td></td><td></td><td></td><td></td></tr>

I've seen lots of issues with this kind of formatting. Have you tried messing with <col>?
For example, (I know the numbers are probably off, but you can adjust as needed):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head></head>
<body>
<table border='1' width="1000px" style='border-collapse: collapse' >
<col width='180' /><col width='180' /><col width='180' /><col width='180' />
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr valign="top"><td colspan="1" ><div style="width:180px;border: solid 1px black;">1</div></td><td colspan="3" ><div style="width:770px;border: solid 1px black;">2</div></td></tr>
<tr valign="top"><td colspan="4" ><div style="width:960px;border: solid 1px black;">3</div></td></tr>
<tr valign="top"><td colspan="2" ><div style="width:475px;border: solid 1px black;">4</div></td><td colspan="2" ><div style="width:475px;border: solid 1px black;">5</div></td></tr>
</table>
</body>
</html>
See http://www.w3.org/TR/html4/struct/tables.html#h-11.2.4.2 For more info

What about the code is not working as expected? I tried your sample code and it works as it should: there are 4 columns in the table; the first row is empty, the second has two columns, one large and one short, the third row has one column that spans the whole table, and the fourth row has 2 columns.
I should point out that the divs inside the table don't necessarily match the widths of the columns they are in. That is because of the way table column widths are computed: The table has a fixed width (1000px). The columns are distributed within these 1000 px to best fit the containing data.
Row 1 says nothing about the column widths.
Row 2 says column1 must be at least 180px and column 2+3+4 must be at least 770px.
Row 3 says columns 1+2+3+4 must be at least 960px.
Row 4 says columns 1+2 must be at least 475px and columns 3+4 must be at least 475px.
Since nothing is said about column2, and column2 contains no data, it is being sized to the minimum width, and column1 is being sized to a larger width than you expect.
You can fix this problem by specifying the widths in the columns themselves, either using the <col> syntax, a CSS rule, or specifying the size in the first row of the table (using <td width="">.

This is an artifact of your css conflicting with your table widths (or lack thereof).
This code defines the cell widths in the first row, and then uses css to make the encosed divs fill the cells:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<style>
td div {
width:100%;
border: solid 1px black;
}
</style>
</head>
<body>
<table border=1 width="1000px" >
<tr><td width="18%">18%</td><td width="30%">30%</td><td width="26%">26%</td><td width="26%">26%</td></tr>
<tr valign="top"><td colspan="1" ><div>18%</div></td><td colspan="3" ><div>82%</div></td></tr>
<tr valign="top"><td colspan="4" ><div>100%</div></td></tr>
<tr valign="top"><td colspan="2" ><div>48%</div></td><td colspan="2" ><div>52%</div></td></tr>
</table>
</body>
</html>
The main issue is that you are defining widths for divs inside of table cells, expecting them to force your table into shape. In reality, your first cells (the empty ones on the top) have no defined width, so when you span across those undefined widths, you get more undefined width, and then you shoehorn some sized divs into them. You should probably either set your divs to 100% width, and size your cells, or simply style your cells, eliminating the divs altogther.
Best of all, just use css and divs, without a table, but I understand that that can be an exercise in frustration, especially if you are new to css.

Related

Same column width under colspan

How can I make columns under colspan of same width?
I have table header like in example.
<html>
<head>
<style>td {border: solid 1px black;}</style>
</head>
<body>
<table style="width: 100%;border-collapse: collapse;">
<tr>
<td rowspan="2">Some header columns or even several(big or small)</td>
<td colspan="4">pre-defined number of undercolumns</td>
</tr>
<tr>
<td>1</td><td>11</td><td>111</td><td>1111</td>
</tr>
<tr>
<td>data_row</td><td>4444</td><td>333</td><td>22</td><td>1</td>
</tr>
</table>
</body>
</html>
I have created a jsFiddle that demonstrates this.
Potentially the number of columns (to make same width) could be different. Changing the table-layout to fixed is not a solution in my case because of existence of other columns. I can not make them with fixed width since not sure of data content length. I also can not do them with percent width since it is percent of all table, but not column group.
You can try this:
td {
border: solid 1px black;
width: calc(100%/5);
}
And you can divide the width as many columns as you have.

How to workaround Chrome column-width bug?

Chrome has a bug that seems unlikely to get fixed anytime soon:
https://code.google.com/p/chromium/issues/detail?id=178369
Basically it happens that Chrome can't handle column widths correctly if the cells themselves contain "width=100%" elements.
I need the 100% width elements in the cells.
Does anybody know a workaround for that bug?
Testcase:
<table style="width: 800px; border: 1px solid black">
<tr>
<td>
<table style="width: 100%; border: 1px solid blue">
<tr>
<td style="width: 100%; background: red;">
1
</td>
</tr>
</table>
</td>
<td>
<table style="width: 100%;">
<tr>
<td style="width: 100%; background: green;">
2
</td>
<td>
</td>
</tr>
</table>
</td>
</tr>
</table>
Simply adding
table-layout: fixed
for the outer table should do it. http://jsfiddle.net/ysqx6j4t/
NOTE: Chrome ignores td style widths unless they are set in very first row of a table. (IE used to do that about 15 years ago.)
So you can't have a single td and colspan=n in first row.
I apologize in advance for this being a response and not answer...
It seems that the bug has now infected not only Chrome, but also newer versions of Opera and Vivaldi. None of these work-around suggestions work with Chrome, Vivaldi, Opera (newer releases!), even if style widths are set in the first row, and especially if any column in that first row has a 'min-width' set -- a greedy (ie 100% is ignored).
Setting a column width to 100% so that is 'greedy' DOES work in all versions of Firefox (all the way back to version 3.5!). It also works in Opera 12 (!) but not Opera 65 -- [which shows that just copying someone else's code is not always productive.]
An aHA moment -->
The actual bug is this:
If a cell (in any column, not necessarily the first col in the first row) spans multiple columns, and attempts to force the colspan to be greedy, that ends up being applied to the first column ONLY - not to the group.:
So,
<!-- EXAMPLE 0 -->
...
<tr >
<td colspan=4>
<td colspan=8>
<table border=0 cellspacing=0 cellpadding=0 width=100% style="font-size:11pt;">
<tr style="font-size:8pt;">
<td width=100%><hr>
<td class=pnote> SYNOPSIS / EXAMPLE</tr>
<tr ><!-- THIS IS WHERE IT WENT WRONG IF THE CELL
had any markup in addition to colspan=2 -->
<td colspan=2><b>layerinfo = </b>App.Do (Environment, 'ReturnLayerProperties', {})
<!-- another solution is to encapsulate everything in this row/cell in another table ...
<td colspan=2><table width=100%...
</table>
-->
<tr style="font-size:8pt;">
<td width=100%><hr>
<td class=pnote> RETURNS</tr>
<tr >
<td width=100% nowrap><b>layerinfo : {</b>
<td class=pnote> </td>
...
</table></tr>
And the result now is correct [(a) the and the label no longer split the row equally, nor (b) the text on the spanned cell no longer defines the width
of the first column of the table. (wierd, but it happened)

Table cells(td, th) doesn't take width given in colgroup

I am trying to give min width to table cells using col element of colgroup. The table is wrapped by a div which has some width set(less than combined width of all cells set in col) and overflow of div is set to auto.
Here is my html code -
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.table-block {
border-spacing: 0;
border-collapse: collapse;
}
.cell {
padding: 5px 10px;
border: 1px solid silver;
}
</style>
</head>
<body>
<div style="width:200px;overflow: auto">
<table class="table-block">
<colgroup>
<col style="width:300px">
<col style="width:300px">
</colgroup>
<tbody>
<tr>
<td class="cell"><em>2(0,2)</em></td>
<td class="cell"><em>3(0,3)</em></td>
</tr>
<tr>
<td class="cell"><em>2(0,2)</em></td>
<td class="cell"><em>3(0,3)</em></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
My problem is cells doesn't take width from col. It is trying to fit themselves in the wrapper div. I want that the cells take the proper width given and a scrollbar should appear. I have a solution that I set table width set to the total width I need. This would require me to update table width every time I insert new column by JavaScript.
My Solution -
<div style="width:200px;overflow: auto">
<table class="table-block" style="width:600px">
<!-- table things -->
</div>
Is it a right thing to do? And why it happens?
jsFiddle link
I think the problem here is that ultimately the table defaults to 100% width of the container, and its inner elements are unable to surpass this without their content forcing it to do so. The same happens when attempting to give a tr or td a width greater than the table's own.
Your fix is pretty much the way I'd do it. The only change I'd make is:
<div style" ... overflow-x:scroll; overflow-y:hidden;">
This way a scroll bar won't appear down the side on older versions of IE.
This of course assumes that you only want your table to scroll horizontally.

Styling the width of tables cells

I have a problem choosing the table cells.
I defined my table cells to have the following measurements:
cell 1: 220px
cell 2: 315px
cell 3: 265px
cell 4: 200px
Adds to 1000px
The measurements that I get when opening the table in a browser:
cell 1: 190px
cell 2: 264px
cell 3: 222px
cell 4: 168px
Adds to 844px
Note that I dont set the width of the table. I also have no other elements on the page apart from that table. Why does that happen?
Try this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css" media="screen">
table { border-collapse: collapse; table-layout: fixed }
td { padding: 0; border: 1px solid black }
</style>
</head>
<body>
<table>
<col width="220" />
<col width="315" />
<col width="265" />
<col width="200" />
<tbody>
<tr>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
<td>col 4</td>
</tr>
</tbody>
</table>
</body>
</html>
col is legal element used to layout the table cells.
In the above examples Firebug will show the cells' width with the desired size in pixels minus 1px for borders (which will collapse). The entire table will be exactly 1000px wide.
We really need more code to asses this. Please create a demo js-fiddle.
Did you use the style-rule: table-layout:fixed; border-collapse: collapse; on the table itself, together with the attributes: border="0" cellpadding="0" cellspacing="0"?
Did you also set the intended total table width of 1000px?
Set the width of your table, ad you'll get the correct result.
See this fiddle.

Different behavior of padding-bottom in table row between IE and FF

Kindly read the following code as an example (pay attention to the "padding-bottom" of 2nd table row):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head><title>test</title></head>
<body>
<table style="height:300px;width:200px;background:#660000; float:left">
<tr><td style="height:20px">first row</td></tr>
<tr><td style="height:180px;padding-bottom:20px;">second row</td></tr>
<tr><td style="height:180px;">third row</td></tr>
</table>
<table style="height:300px;width:200px;background:#006600; float:left">
<tr><td style="height:20px">first row</td></tr>
<tr><td style="height:180px;">second row</td></tr>
<tr><td style="height:180px;">third row</td></tr>
</table>
</body>
</html>
I expect that height of two tables should be the same in both IE and FF.
However, FF renders it as expected, but in IE, the first table is 20px higher than the second table. What should I do in order to make it render like FF?
I am also curious about what makes the difference.
IE and Firefox have different rules around how the box model works.
The best way to think of this is that IE is taking the set height of that cell then adding the padding to it. This results in a cell height of 200px.
Whereas Firefox is taking the height of the content of the cell, then applying the padding to it. Because the content height + padding does not exceed the set height of the cell, the cell is not expanded.
You might try playing with a couple of doctypes to see if you can get them to match up, but I dont think IE 7 and FF3 match up for this situation regardless of DOCTYPE. Also, look into possibly using a reset style sheet to get the default margin's, font sizes, etc to match.
I took your test and did the following to make it looks the same in both browsers:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>test</title>
<style>
* {margin:0px; padding:0px;font-family: arial;font-size:14px;}
span { border: solid 1px black; margin-top:4px;display:block;}
.first { border:solid 1px blue; }
.second {border:solid 1px orange; }
.third {border:solid 1px yellow;}
.paddit {padding-bottom:10px;height:180px;}
</style>
</head>
<body>
<table style="width:200px;background:#660000; float:left">
<tr valign="top">
<td class="first" style="height:20px;"><span>first row</span></td>
</tr>
<tr valign="top">
<td class="second paddit"><span>second row. This is a long test to see what happens when a lot of content is placed in here; and I need more content.This is a long test to see what happens when a lot of content is placed in here; and I need more content.This is a long test to see what happens when a lot of content is placed in here; and I need more content.</span></td>
</tr>
<tr valign="top">
<td class="third" style="height:180px;"><span>third row</span></td>
</tr>
</table>
<table style="width:200px;background:#006600; float:left">
<tr valign="top">
<td class="first" style="height:20px;"><span>first row</span></td>
</tr>
<tr valign="top">
<td class="second" style="height:180px;"><span>second row</span></td>
</tr>
<tr valign="top">
<td class="third" style="height:180px;"><span>third row</span></td>
</tr>
</table>
</body>
</html>