views:

239

answers:

4

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"&gt;
<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.

A: 

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"&gt;
<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

bradlis7
A: 

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"&gt;
<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.

Jeff B
A: 

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="">.

Mr. Shiny and New
+2  A: 

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>
bobince