Lesson 12

Ready for the second instalment in the Tables saga? Then let's press on with the next trick.

So far the tables we've looked at have been pretty straightforward in that there's data in every cell, save the occasional empty one. But it's often useful in tables to have cells that span more than one column of more than one row. Cells like this often contain headings or graphics. Look at this example of what I mean.
Spanning rows and columns is achieved by using the rowspan and colspan attributes in the <TD> or <TH> tags. The principle is quite simple, but with complex tables can be a little tricky in practice.You have to think about it very methodically. So let's start with a simple case. Study the code below:
<HTML>
<HEAD>
<TITLE>Lesson 12</TITLE>
</HEAD>
<BODY>
<TABLE border="1" cellpadding="5" cellspacing="0">
<TR>
<TH colspan="2">Grape Varieties</TH>
</TR>
<TR>
<TD>Red</TD>
<TD>White</TD>
</TR>
<TR>
<TD>13</TD>
<TD>17</TD>
</TR>
</TABLE>
</BODY>
</HTML>
Now check it out in your browser.
The table has two columns, but we made the cell in the first row span both columns by including the colspan="2" ("2" being the required number of columns to span) in the <TH> tag. Because there are now no other cells in this row, there are no further <TD> or <TH> declarations. The remaining two rows each show tags for two cells.
Let's look at an equally simple example of spanning rows:
<HTML>
<HEAD>
<TITLE>Lesson 12</TITLE>
</HEAD>
<BODY>
<TABLE border="1" cellpadding="5" cellspacing="0">
<TR>
<TH rowspan="2">Grape Varieties</TH>
<TD>Red</TD>
<TD>13</TD>
</TR>
<TR>
<TD>White</TD>
<TD>17</TD>
</TR>
</TABLE>
</BODY>
</HTML>
Now check it out in your browser.
In this case, we have a cell that spans two rows. Note that we included the rowspan="2" attribute in the tag for the cell concerned in the first row, and it isn't necessary to define an empty cell in the first position on the next row: we just move on to the definitions of the remaining cells. So in our second row, we only have tags for two cells, because the first was spanned by a cell in the previous row. Are you still with me? Good!
The key point to remember is that cells always span downwards and to the right. If you want a cell that spans several columns, add the colspan attribute into the tag for the leftmost of the spanned cells, and omit tags for the rest of the spanned cells. If you want a cell that spans several rows, add the rowspan attribute into the tag for the topmost of the spanned cells, and omit tags for the rest of the spanned cells.
It's time now to examine a more complex example with a complete explanation of how the table is constructed. Be sure to maximise the new browser window that opens with the example.
Once you understand these principles you can move on to the next table topic.

We've seen how in the absence of any instructions, table cells will size themselves automatically to accommodate the data in the cell. Unless that would make the whole table wider than the browser window -- the table will always stay within the confines of the browser window, causing text to wrap around inside the cells as necessary. If you want to remind yourself of this, just look at this example and try re-sizing the browser window to see the effect.
Table width
We can control the width of tables in two ways: by percentage of the browser window width, or by the exact width in pixels. These are specified in the width attribute of the <TABLE> tag. Let's start by looking at the percentage method.
The code example below will produce a table with only one row and three cells. Each of these cells contains only a short string of text, so normally the table would not be particularly wide. But I've included the attribute width="100%" in the <TABLE> tag, which will cause the table to expand to fill the entire width of the browser window, however wide that might be. Examine the code now:
<HTML>
<HEAD>
<TITLE>Lesson 12</TITLE>
</HEAD>
<BODY>
<TABLE width="100%" border="1" cellpadding="5" cellspacing="0">
<TR>
<TD>A small cell</TD>
<TD>Another small cell</TD>
<TD>And another</TD>
</TR>
</TABLE>
</BODY>
</HTML>
Now check out the result. Try re-sizing the browser window, and you'll see that the table expands or contracts so that it always fills the window.
If we now change the width attribute to width="75%", the table will occupy three-quarters of the browser window width, regardless of how we re-size it. Test it for yourself.
There are limits, however. If you try to make the window very narrow, you'll find there's a minimum width below which the table simply will not go -- this is driven by the width of the largest single word in each cell, because a word can't be broken in the middle to wrap around to the next line.
Turning now to the other method, we can set the exact width in pixels. Using the same example as before, this time we'll set the width at 800 pixels. Here's the code:
<HTML>
<HEAD>
<TITLE>Lesson 12</TITLE>
</HEAD>
<BODY>
<TABLE width="800" border="1" cellpadding="5" cellspacing="0">
<TR>
<TD>A small cell</TD>
<TD>Another small cell</TD>
<TD>And another</TD>
</TR>
</TABLE>
</BODY>
</HTML>
Now check out the result. You'll find that re-sizing the browser window has no effect on the table width. It stays fixed at 800 pixels, and if your browser window is narrower than 800, you'll have to scroll sideways to see all of the cells.
Cell width
Being able to set the width of the table isn't the end of the story (it never is, is it?). We can also set the width of individual cells, by using the width attribute in the <TD> or <TH> tag, with either a percentage or an absolute pixel value. But: use of the width attribute in the <TD> and <TH> tags is deprecated, and the HTML specifications recommend that you use CSS for this purpose. However, as in other cases where I've told you abut a deprecated tag or attribute, until such times as everyone is using a CSS-capable web browser, then this attribute will continue to be a useful tool for web page builders.
That said, consider this example:
<HTML>
<HEAD>
<TITLE>Lesson 12</TITLE>
</HEAD>
<BODY>
<TABLE width="600" border="1" cellpadding="5" cellspacing="0">
<TR>
<TD width="60%">60% of table width</TD>
<TD width="40%">40% of table width</TD>
</TR>
</TABLE>
</BODY>
</HTML>
Here we have used an absolute value in pixels to set the width of the table to 600 pixels. In the two cells, we've used percentage values to set how much of the total width each cell should take: 60% for the first, and 40% for the second. Now you can check how it works.
Pretty straightforward, huh? Now let's look at it using absolute values. Take this example:
<HTML>
<HEAD>
<TITLE>Lesson 12</TITLE>
</HEAD>
<BODY>
<TABLE border="1" cellpadding="5" cellspacing="0">
<TR>
<TD width="200">A 200 pixel cell</TD>
<TD width="300">A 300 pixel cell</TD>
</TR>
</TABLE>
</BODY>
</HTML>
In this case, I've set the first cell to be 200 pixels wide, and the second to be 300. Note that there isn't any width attribute in the <TABLE> tag. There isn't any need; the width of the table will be the combined width of the cells. Check it out.
But try re-sizing the browser window. You'll find that as long as the window is wider than 500 pixels (200 plus 300) the table is unaffected, but if you make the window smaller than 500 pixels then the table shrinks to fit. If you don't want this to happen, then add a width="500" attribute to the <TABLE> tag. I've done that for this example -- try it out.
So by combining the use of the width attribute in both the table and the cell tags, we can fix the overall width of the table, and the widths of the columns. Of course, you need to make sure that everything adds up. In other words, the value of the width attribute in the <TABLE> tag must be equal to the sum of the widths of the various columns.
What happens if you get it wrong? Well, here's a simple example:
<HTML>
<HEAD>
<TITLE>Lesson 12</TITLE>
</HEAD>
<BODY>
<TABLE width="400" border="1" cellpadding="5" cellspacing="0">
<TR>
<TD width="200">A 200 pixel cell, supposedly</TD>
<TD width="300">A 300 pixel cell, supposedly</TD>
</TR>
</TABLE>
</BODY>
</HTML>
Here, our two cells add up to 500 pixels -- but the table width has been set at only 400. What takes precedence in this conflict? Take a look at the result, then we'll discuss it.
The resulting table is only 400 pixels wide, not 500. In other words, the value of width in the <TABLE> tag takes precedence. So how does the browser decide what width to make the columns? It's done by proportion. The 200 pixel cell is assigned a width that is two-fifths of the total width, and the 300 pixel cell is given three-fifths of the total width:
200
----------- x 400 = 160 pixels
(200 + 300)
300
----------- x 400 = 240 pixels
(200 + 300)
Common sense probably tells you that there is no need to specify the width of every cell in every row. Once you've set the width of a cell in any one column, then that's the width that will be adopted for the whole column. If by mistake you set the width of two cells in the same column, and you've assigned different widths, then the widest will take precedence. Study the following code:
<HTML>
<HEAD>
<TITLE>Lesson 12</TITLE>
</HEAD>
<BODY>
<TABLE border="1" cellpadding="5" cellspacing="0">
<TR>
<TD width="200">A 200 pixel cell, supposedly</TD>
<TD width="200">A 200 pixel cell, supposedly</TD>
</TR>
<TR>
<TD>A 200 pixel cell, supposedly</TD>
<TD width="300">A 300 pixel cell, supposedly</TD>
</TR>
</TABLE>
</BODY>
</HTML>
You can see that here we've put a width attribute in the second cell of each of the two rows, and the values conflict. The browser will take the larger of the two, making this column 300 pixels -- you can verify this now.

In all of the examples we've used up to now, the table contents have always been text. You might be asking: can we put images in tables? The answer is "Yes", and I'm thankful that we can. Just to be clear on this point, we can put any kind of content in table cells. All of the HTML elements we've encountered so far -- paragraphs, lists, all the formatting and style elements -- can all be put inside tables.
Horizontal and vertical alignment of images in cells follows the same rules we have seen before, using the align and valign attributes in the relevant tags. Study the code below:
<HTML>
<HEAD>
<TITLE>Lesson 12</TITLE>
</HEAD>
<BODY>
<TABLE border="1" cellpadding="5" cellspacing="0" bgcolor="#FFFFCC">
<TR>
<TD>This text is just<BR>
padding to make<BR>
sure that the<BR>
cells are higher<BR>
than the images<BR>
inside them, so<BR>
that you can see<BR>
the effect of the<BR>
vertical alignment<BR>
attributes on the<BR>
position of the<BR>
images.</TD>
<TD width="150" align="left" valign="top"><IMG src="whereami.gif"><BR>Top Left</TD>
<TD width="150" align="center" valign="middle"><IMG src="whereami.gif"><BR>Middle Centre</TD>
<TD width="150" align="right" valign="bottom"><IMG src="whereami.gif"><BR>Bottom Right</TD>
</TR>
</TABLE>
</BODY>
</HTML>
In this example, I've forced the table height and cell widths to guarantee the cells will be larger than the images being placed inside them, so that you can see the alignment effect clearly. Each cell has a few words of text in it too (which of course, obey the same alignment rules). Check it out in your browser.

Just moments ago, I said that you can put any kind of content into a table cell. And that includes -- another table! This adds greatly to the flexibility of tables, particularly when used as a page layout tool. However, the code can become very confusing. And while it is theoretically possible to nest tables inside tables inside tables ad infinitum, I wouldn't recommend it: it has a detrimental effect on the time taken for the browser to render the page. So don't nest tables more than a couple of levels deep.
Anyway, to prove that it can be done, take a look at this example, complete with its code. This shows a two-row, three-column table with a similar two-row three-column table nested inside one of the cells of the first table. I've given the tables two different background colours to make the nested table stand out better.
Of course, you can use all the width attributes you like in the nested tables as well as the parent tables -- just watch out for conflicting values.

Picking up from the last lesson, we first discovered that we can make tables much more presentable by using the rowspan and colspan attributes to get cells to span more than one row or column at a time. These attributes can be used in both the <TD> and <TH> cell tags.
We can control the width of tables and cells by applying the width attribute to the <TABLE>, <TD> or <TH> tags. This attribute takes a value either in percent, in which case it relates:
to the width of the browser window, when used in the <TABLE> tag
to the width of the table, when used in the <TD> and <TH> tags
or in absolute pixel values. Where values for the table width and the sum of the cell widths are in conflict, the table width will generally take precedence.
(Just remember that use of the width attribute in <TD> and <TH> tags is deprecated. It's absolutely OK in the <TABLE> tag, though.)
Images can also be put into table cells -- we simply put the relevant <IMG> tag between the <TD> and </TD> tags (or <TH> and </TH>).
We can nest entire tables inside table cells, theoretically without limit. In practice, nesting tables more than a few levels deep slows down browser rendering, and the code becomes very difficult to follow!
<< Go back to Lesson 11 | Top | Go on to Lesson 13 >>
Copyright © Keith W Bell, 1999 - 2001
This page last updated 1 February 2001
http://www.campanile.org/tutorials/html/lesson12.html
|