HTML Tables
(last updated: Jun 6, 2008)

Select font size:

HTML Tables

HTML Tables (see HTML4.01 specs) provide a robust way of organizing information on a web page. They can be used both to construct an overall grid-style page layout as well as for presenting specific information in a tabular fashion.

Basic elements: table, tr, td, th

The most basic HTML elements needed are table, tr (table row) and td (table data). In addition, the th (table header) element is used like the td element with different default style settings. For example, this is a simple table using these basic elements.
<table summary="">

<tr>
<th>1990</th> <th>2000</th> <th>type</th>
</tr>

<tr> 
<td>5.31</td> <td>4.2</td> 
<td>percent increase</td>
</tr>

<tr>
<td>$30,333</td> <td>$46,576</td> 
<td>
hardware<br />and<br />software
</td>
</tr>

</table>
Here is how it is rendered:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software

The control for table elements are in HTML-Kit's table tab. The icon on the far left is the most basic one which generates a starter table with one row and one cell. HTML-Kit more-or-less forces you to use the summary attribute.

A table consists of cells displayed horizontally between the <tr> </tr> tags. The td and th cells have the same function — the difference is their different default style features:

Table attributes

The attributes specific to the table element are these (see the HTML4.01 table specs): In order to illustrate the effects of these attributes, we'll use the table from the previous section and make changes to the start tag.

The border, cellpadding, cellspacing attributes

The border attribute is the easiest way to control the appearance of having a frame around the table. For example, modifying the start tag as follows:
<table summary="" border="1">
causes the table to look like this:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
The cellpadding attribute creates space between the cell content and the surrounding cell. Making this addition:
<table summary="" border="1" cellpadding="20px">
causes the table to look like this:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
The cellspacing creates space between cells. Making this addition:
<table summary="" border="1" cellpadding="20px" cellspacing="8px">
causes the table to look like this:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software

The cellpadding and cellspacing both have default values of 1. In many circumstances it is useful to eliminate this spacing, causing the following change in appearance (both have border="1"):
cellpadding="0"
cellspacing="0"
cellpadding, cellspacing unspecified
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software

The width attribute

The width attribute specifies the width of the table, the default unit being pixels. Making the start tag this:
<table summary="" border="1" width="400px">
causes the table to look like this:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
It is also useful to set the width using the percentage unit with the suffix %. In this case the width is set to the percentage of the browser's width and, of course, varies when the browser is resized. Making the start tag this:
<table summary="" border="1" width="100%">
causes the table to look like this:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software

The frame and rules attributes

The frame and rules attributes allow you to specify variations on where the lines appear. The frame specifies the lines forming the external box around the table and the rules specify the internal lines. Here are some examples.

<table summary="" border="1" frame="border" rules="none">
causes the table to look like this:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
<table summary="" border="1" frame="void" rules="all">
causes the table to look like this:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
<table summary="" border="1" frame="hsides" rules="rows">
causes the table to look like this:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
<table summary="" border="1" frame="hsides" rules="cols">
causes the table to look like this:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software

Empty Cells

When you want a cell to be empty or blank and there is a border, you typically cannot simply do this:
<td></td>       or       <td> </td>
For example, the following code:
<table summary="" cellpadding="10px" border="1">
<tr>
<td>a</td>  <td> </td>
</tr>

<tr>
<td>c</td>  <td>d</td>
</tr>
</table>
creates this appearance:
a
c d
What you need to do is to put the special character &nbsp; (non-blocking space) in an empty cell, like this:
<td>&nbsp;</td>
With this modification the empty cell "looks right":
a 
cd

Row and cell attributes

The tr attributes apply to all the cells within the row: (see HTML 4.01 tr specs): The td and th elements share the same attributes (see HTML4.01 td & th specs): Setting the width of an individual cell has the effect of setting the width of the entire column. Its usage is technically deprecated but it is still very common in practice.

Additionally cell and row elements support these attributes

related to providing tabular information in alternative modalities, such as speech synthesis. Using these, the user may be able to query the contents of the table to discover specific information.

We'll use our example table to illustrate some of these features.

Alignment: align and valign

Recall how the original table looks with a border and no other modifications:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
We already talked about the default horizontal alignment for the cells td ("left") and th ("center"). Observe the default vertical alignment for these cells is "center". Now suppose we make the following alignment changes to the rows:
<table summary="" border="1">

<tr align="left">
<th>1990</th> <th>2000</th> <th>type</th>
</tr>

<tr> 
<td>5.31</td> <td>4.2</td> 
<td>percent increase</td>
</tr>

<tr valign="top">
<td>$30,333</td> <td>$46,576</td> 
<td>
hardware<br />and<br />software
</td>
</tr>

</table>
To see the difference, compare the two side by side:

previous version

1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software

modified version

1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
The th and td alignment settings can specify alignment for individual cells and override any setting from the table row. For example, if we make one further modification to the previous table by changing one cell:
<th align="right">type</th>
we get the following effect:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software

Spanning multiple cells: colspan & rowspan

Setting the colspan attribute to a number > 1 allow a cell to cover more than one column. Consider our running example modified yet again:
<table summary="" border="1">
<tr>
<th>1990</th> <th>2000</th> <th>type</th>
</tr>

<tr> 
<td align="center" colspan="2">5.31</td> 
<td>percent increase</td>
</tr>

<tr>
<td>$30,333</td> <td>$46,576</td> 
<td>
hardware<br />and<br />software
</td>
</tr>
</table>
creates this appearance:
1990 2000 type
5.31 percent increase
$30,333 $46,576 hardware
and
software

We are trying to convey the information that the number "5.31" applies to both years instead of repeating it. Whenever a colspan > 1 is used, we simply reduce the number of cells within a row appropriately.

Likewise, the rowspan attribute, when set to a number > 1 means that the cell covers that one in the row where it is declared and the row below it. This is a bit trickier to use, because you have to take away a cell in the next row! Here is an example:
<table summary="" border="1">
<tr>
<th>1990</th> <th>2000</th> <th>type</th>
</tr>

<tr> 
<td>5.31</td> <td align="center" rowspan="2">?</td> 
<td>percent increase</td>
</tr>

<tr>
<td>$30,333</td> 
<td>
hardware<br />and<br />software
</td>
</tr>
</table>
creates this appearance:
1990 2000 type
5.31 ? percent increase
$30,333 hardware
and
software
We are trying to convey the information that the data for the year 2000 is completely unknown.

Row groups: the tbody, thead, tfoot elements.

The elements thead, tbody and tfoot are used to create logically separate row groups. See the (relevant HTML4.01 specs). Their attributes are the same as the tr attributes but they provide a more convenient way to apply a set of attributes to a group of rows at a time. Furthermore, the table lines can be specified to respect the groups.

The thead and tfoot groups are meant to function so that whatever rows are put into them go to the top and bottom of the table, respectively. However, I wouldn't count on this actually working. In fact, you really only need the tbody element since it can be used whenver you want to create a row group.

Let's revisit our working example from the last set of notes with border and cellpadding specified:
<table summary="" border="1" cellpadding="10px">

<tr>
<th colspan="3">Source: RTFM bulletin</th>
</tr>

<tr>
<th>1990</th> <th>2000</th> <th>type</th>
</tr>

<tr> 
<td>5.31</td> <td>4.2</td> <td>percent increase</td>
</tr>

<tr>
<td>$30,333</td> <td>$46,576</td> 
<td>hardware<br />and<br />software</td>
</tr>

</table>
which gives us this appearance:
Source: RTFM bulletin
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software

Attributes for multiple consecutive rows

Suppose, for example, that we want to right-align every cell in the table except for the cell in the first row. So far we have two alternative ways to do this:
  1. add "align=right" to 9 cells, i.e., the td and th tags
  2. add "align=right" to 3 rows, i.e., to the tr tags
Clearly the latter alternative is better than the former, but there is still a simpler way to do this:
  1. surround the 3 rows by <tbody> </tbody> and add "align=right" to the tbody tag
Here is the table with the suggested addition:
<table summary="" border="1" cellpadding="10px">

<tr>
<th colspan="3">Source: RTFM bulletin</th>
</tr>

<tbody align="right">

<tr>
<th>1990</th> <th>2000</th> <th>type</th>
</tr>

<tr> 
<td>5.31</td> <td>4.2</td> <td>percent increase</td>
</tr>

<tr>
<td>$30,333</td> <td>$46,576</td> 
<td>hardware<br />and<br />software</td>
</tr>

</tbody>

</table>
and here is its appearance:
Source: RTFM bulletin
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software

Row groups with rules="groups"

Another usage of row groups is to specify that the internal lines of a table should separate row groups only, not all rows. Recall the attribute values for rules in the table attributes. In this case we want to use rules="groups" setting. Here is our same example modified to illustrate this feature:
<table summary="" border="1" frame="box" rules="groups" cellpadding="10px">

<tr>
<th colspan="3">Source: RTFM bulletin</th>
</tr>

<tr>
<th>1990</th> <th>2000</th> <th>type</th>
</tr>

<tbody>

<tr> 
<td>5.31</td> <td>4.2</td> 
<td>percent increase</td>
</tr>

<tr>
<td>$30,333</td> <td>$46,576</td> 
<td>hardware<br />and<br />software</td>
</tr>

</tbody>

</table>
and here is its appearance:
Source: RTFM bulletin
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
The rules delineate the groups we've created. We'll see in the next section how to create column groups towards the same end.

The colgroup and col elements.

The colgroup and col elements allow us to specify information about entire columns or groups of columns (see HTML4.01 colgroup and col specs). Both of these elements have these attributes: When used, these elements are placed right after the table start tag. In particular, the width attribute, used in td or th elements, is more correctly used in col or colgroup elements, since the width of a single cell really affects the width of the entire column.

Unfortunately, the col and colgroup elements may not work uniformly across all browsers and using the width in td and th elements, although deprecated, often creates more portable HTML code.

Here is an example using the col element:
<table summary="" border="1" cellpadding="10px">
<col span="2" width="200" ></col> 

<tr>
<th colspan="3">Source: RTFM bulletin</th>
</tr>

<tr>
<th>1990</th> <th>2000</th> <th>type</th>
</tr>

<tr> 
<td>5.31</td> <td>4.2</td> <td>percent increase</td>
</tr>

<tr>
<td>$30,333</td> <td>$46,576</td> 
<td>hardware<br />and<br />software</td>
</tr>

</table>
and here is its appearance:
Source: RTFM bulletin
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
In the above example we've use the span attribute to specify the number of columns over which the width has an effect.

The colgroup elements constructs a column group much as the tbody elements construct row groups.

Using colgroup with rules="groups"

The colgroup element functions just like the col element, except that it creates a group of columns which can be used by the rules="groups" setting. For example,
<table summary="" border="1" frame="box" rules="groups" cellpadding="10px">
<colgroup span="2"></colgroup>

<tr>
<th colspan="3">Source: RTFM bulletin</th>
</tr>

<tr>
<th>1990</th> <th>2000</th> <th>type</th>
</tr>

<tr> 
<td>5.31</td> <td>4.2</td> <td>percent increase</td>
</tr>

<tr>
<td>$30,333</td> <td>$46,576</td> 
<td>hardware<br />and<br />software</td>
</tr>

</table>
has this appearance
Source: RTFM bulletin
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
The col and colgroup elements can be combined in various ways. You can place col elements between the start and end tags of colgroup elements if you so desire.

Example using rowgroups and colgroups

When the rules="groups" table attribute setting is chosen usually we want to specify both row groups and column groups to get the right visual effect. Here is an example:
<table summary="" border="1" frame="box" rules="groups" cellpadding="10px">
<colgroup span="2"></colgroup>

<tbody>
<tr>
<th colspan="3">Source: RTFM bulletin</th>
</tr>
</tbody>

<tr>
<th>1990</th> <th>2000</th> <th>type</th>
</tr>

<tbody valign="top">
<tr> 
<td>5.31</td> <td>4.2</td> <td>percent increase</td>
</tr>

<tr>
<td>$30,333</td> <td>$46,576</td> 
<td>hardware<br />and<br />software</td>
</tr>
</tbody>

</table>
which looks like this:
Source: RTFM bulletin
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software

Table-related style properties

Many of the style properties can apply to tables and replace the table attributes: For example, using the table from Notes 4:
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software
If we set
<table class="special" summary="" border="1">
in conjunction with the rules:
table.special {
  width: 400px;
}
table.special th {
  text-align: left;
}
table.special td {
  padding: 0px 10px 0px 10px;
  vertical-align: bottom;
}
we get
1990 2000 type
5.31 4.2 percent increase
$30,333 $46,576 hardware
and
software

Style-generated table lines

For example, we can create red line borders within a table using the following style rules:
table.redlines { border: solid 1px red; }
table.redlines td {
  border: solid 1px red;
  padding: 10px;
}
When applied to this table:
<table class="redlines">
<tr><td colspan="2">A</td></tr>
<tr>
<td>B</td> <td>C</td>
</tr>
</table>
we get this result:
A
B C
This example illustrates that the default cellspacing setting of the table is not 0. If we do set it to 0 in the following modified table:
<table cellspacing="0" class="redlines">
<tr><td colspan="2">A</td></tr>
<tr>
<td>B</td> <td>C</td>
</tr>
</table>
yields the result:
A
B C
The result that we effectively double the given line thickness in order to achieve single lines. If you really want the single border (not doubled), you have to limit the border specifications in the style rules, something like this:
table.redlines1 { 
  border-top: solid 1px red; 
  border-right: solid 1px red; 
}
table.redlines1 td {
  border-left: solid 1px red;
  border-bottom: solid 1px red;
  padding: 10px;
}
When applied to this table:
<table cellspacing="0" class="redlines1">
<tr><td colspan="2">A</td></tr>
<tr>
<td>B</td> <td>C</td>
</tr>
</table>
we get this result:
A
B C


© Robert M. Kline