Contents

Quick Introduction to HTML
Tables

What are tables for?

The primary purpose of HTML tables is for displaying tabular data in a Web page, that is, information that needs to be displayed in rows and columns.

Tables are also the only reliable way of achieving horizontal alignment of elements using pure HTML.

A basic table

Tables are divided vertically into rows and horizontally into cells. The contents of the table goes in the cells.

Table cell content can be anything that goes into the body of an HTML document: text, images, links, lists, and even other tables.

HTML tables are set off by table tags:

<table>...</table>

which inclose one or more tr (table row) beginning and end tags, like so:

<table><tr>...</tr></table>

which in turn contain one or more td (table data) beginning and end tags, or optionally th (table header) tags, which set off the cells of the row.

<table><tr><td>...</td></tr></table>

The content of the table is put between these td and th tags. The th tags are used to indicate column or row headers; most browsers therefore display them differently from td tags.

For example, this code

<table>
	<tr> <th>header one</th> <th>header two</th> </tr>
	<tr> <td>data one  </td> <td>data two  </td> </tr>
	<tr> <td>data three</td> <td>data four </td> </tr>
</table> 

is rendered as

header oneheader two
data onedata two
data threedata four

The number of rows in the table is the number of tr tags.

The number of columns in the table is the number of columns in the row that has the greatest number of td and th tags.

Some browsers will render table data that is not set off by td and th tags, other browsers will not. For consistent results, put table data only between these tags. You can use spaces between the other tags to make the HTML code easier to read, however (as always, it is ignored by the browser).

Borders

Table cell borders are specified by the border attribute of the table tag. If its value is "0", no borders are drawn. If its value is "1", a thin line border is drawn around each cell. Larger numerical values usually increase the width of the line drawn around the cells.

Building on the previous example, the code

<table border="1">
	<tr> <th>header one</th> <th>header two</th> </tr>
	<tr> <td>data one  </td> <td>data two  </td> </tr>
	<tr> <td>data three</td> <td>data four </td> </tr>
</table> 

is rendered as

header oneheader two
data onedata two
data threedata four

Spacing and padding

The spacing between table cells is adjusted by the cellspacing attribute of the table tag. The padding between the contents of the table cells and the border of the table cells is adjusted by the cellpadding attribute. The value of both these attributes is a number of screen pixels.

Once again building on the previous example, the code

<table border="1" cellspacing="8"> <tr> <th>header one</th> <th>header two</th> </tr> <tr> <td>data one </td> <td>data two </td> </tr> <tr> <td>data three</td> <td>data four </td> </tr> </table>

is rendered as

header oneheader two
data onedata two
data threedata four

while the code

<table border="1" cellpadding="8"> <tr> <th>header one</th> <th>header two</th> </tr> <tr> <td>data one </td> <td>data two </td> </tr> <tr> <td>data three</td> <td>data four </td> </tr> </table>

is rendered as

header one header two
data one data two
data three data four

Most browsers assign default non-zero values to both the cellspacing and cellpadding attributes, so to make a tight table, whose cell contents are adjacent, you have to set both attributes to zero explicitly: the code

<table border="1" cellspacing="0" cellpadding="0"> <tr> <th>header one</th> <th>header two</th> </tr> <tr> <td>data one </td> <td>data two </td> </tr> <tr> <td>data three</td> <td>data four </td> </tr> </table>

is rendered as

header one header two
data one data two
data three data four

This technique is especially important when using tables to align images.

The effect of cell padding and spacing may also be achieved using style margin and padding properties of the cells; this technique is more flexible than using the cellspacing and cellpadding attributes.

Cells spanning multiple rows or columns

It is often important for a table cell to occupy multiple rows or multiple columns. The number of rows or columns a cell is to span is specified by the rowspan or colspan attributes, respectively, of the td or th tag.

For example, this code

<table border="1"> <tr> <td rowspan="3">A one</td> <td>A two</td> <td>A three</td> </tr> <tr> <td>B two</td> <td>B three</td> </tr> <tr> <td colspan="2">C two </td> </tr> </table>

is rendered as

A oneA twoA three
B twoB three
C two

Note that if a cell has a non-zero rowspan, it displaces the cells in its column in the row below it. So in those rows, you do not insert td tags for that column. In the above example, there are no cells “B one” or “C one”.

Likewise, if a cell has a non-zero colspan, it displaces the cells in its row in the columns to its right. So for those columns, you do not insert td tags. In the above example, there is no cell “C three”.

Width and centering

The correct way to specify the width of a table, and to indicate that the table is to be centered, has changed in the transition from HTML version 3 to 4. What is now considered to be the correct method will not be recognized by older browsers; the older methods will not validate as correct HTML 4.

You can specify the width of a table by using the width attribute of the table. Its argument is just the numerical width, in pixels, of the table.

However, in HTML 3, you could also specify a percentage of the width of the containing element (e.g. the document window). If you set the width to "100%", the table would expand to fill the browser window horizontally. The percentage width attribute is not valid in HTML 4.

The HTML 3 way to center a table was to put it between center tags, but this tag has gone away in HTML 4.

The modern, HTML 4 way to specify the width of a table, or a table cell, or anything else, is with the CSS width property, which can take values in terms of various length measurements, or a percentage representing the fraction of the width of the element enclosing the table.

The modern way to center a table is to put it in a div (or any other block element) with style text-align: center, and then to give the table itself style margin: auto.

Notice that giving the table itself the style of text-align: center will not work.

Putting all that together, we have this example

<div style="text-align: center">
	<table border="1" style="margin: auto; width: 50%">
		<tr> <td>a centered table</td> </tr>
		<tr> <td>half the width of its container</td> </tr>
	</table> 
</div>

being rendered as

a centered table
half the width of its container

HTML 4 features

The HTML 4 standard introduced several useful features to tables (as well as making a few obsolete—these I haven’t discussed in this document). Keep in mind that these new features are only recognized by the more recent, higher-powered web browsers.

Caption

A caption is a short textual description associated with a table. It is usually rendered adjacent to the table: above, below or to either side.

To associate a caption with a table, enclose the caption text in caption tags, immediately following the table tag. A table can have no more than one caption.

Table summary

The summary attribute of an HTML 4 table is a textual description of the purpose and structure of the table, primarily for non-visual web browsers.

Column group

Table rows are explicitly set off by the tr tag, but in previous versions of HTML, there was no way to refer to table columns. This resulted in two problems.

The first had to do with column formatting. While you could specify the color of a whole row to be blue by setting the style of the tr tag, there was no way to specify the color of a whole column, short of setting the style of each td tag in the column.

The second had to do with the sizing of columns in very long tables. A browser calculates the number of columns in a table to be the largest number of td elements contained in any tr element in the table. Furthermore, in order to calculate an appropriate width for a column, a browser needs to know the content of all the cells in the column. For both of these calculations, the browser would need to read in and process the entire table before it could properly display the table.

These problems are remedied in HTML 4 with the colgroup and col tags. These allow you to specify formatting styles for an entire column, and give the browser a clue as to the number and width of columns in a long table.

Row group

For some very long tables, it might be useful for the the user to scroll the table content rows while table header (or footer) rows remain stationary.

To indicate table header rows, put the row (or rows) between thead begin and end tags. To indicate table footer rows, put the row (or rows) between tfoot begin and end tags. To indicate table content rows, put rows between tbody begin and end tags.

Any thead or tfoot tag must appear before the tbody tag, so the browser can process them before it must deal with the (possibly very numerous) table content rows. If a thead or tfoot tag is present in a table, there must also be a tbody tag. The thead, tfoot and tbody tags in a table must contain equal numbers of columns.

Frame and rules

The table frame is the graphical box drawn around the table. The rules are the lines drawn between elements.

A table’s frame and rules can be customized using the table tag’s frame and rules attributes.

The frame attribute takes these values:
void, above, below, hsides, vsides, lhs, rhs, box, border.
The default value is void, the valuesbox, border both indicate lines are to be drawn on all four sides of the table. The other values indicate lines are to be drawn only on certain sides of the table.

The rules attribute takes these values: none, groups, rows, cols, all. The default is none, indicating no rules. The value all puts rules between rows and columns. The value groups puts rules between row groups, as defined by the thead, tfoot, tbody elements, and column groups, as defined by the colgroup and col elements. The values rows and cols put lines between rows and between columns, respectively.

Example

This code uses many of these HTML 4 features:

<table border="1" frame="vsides" rules="groups"
	summary="A table showing new HTML 4 features">
<caption>HTML 4 Table</caption>
<colgroup>
	<col width="150" style="background: aqua"/>
	<col width="250" style="background: fuchsia"/>
</colgroup>
<thead style="background: silver">
	<tr><th>header one</th><th>header two</th></tr>
</thead>
<tbody>
	<tr><td>data one</td><td>data two</td></tr>
	<tr><td>data three</td><td>data four</td></tr>
</tbody>
</table> 

It is rendered as

HTML 4 Table
header oneheader two
data onedata two
data threedata four

Style

Styling, in the sense of formatting, affects tables in two ways.

Mostly, style sheets provide a very flexible and convenient means of applying formatting to tables and items within tables. That is, the size and typeface of text, background colors and pictures, etc.

On the other hand, style sheets are replacing many old table attributes; modern flavours of HTML accept fewer and fewer of the old formatting attributes of table elements, in favor of style sheets. Whereas with pure HTML, tables are the only means of providing horizontal alignment, modern CSS can take over much of this role.

A rule of thumb is: use tables for tabular data. Use of tables for alignment of items in a page constitutes breaking the rule “separate presentation from content”, and on these grounds, you should at least try to achieve the effect you want with CSS layout and positioning. Unfortunately, the state of compliance with CSS positioning among one of the most popular web browsers is not great, so your milage may vary.

Gotchas

Many browsers, by default, don’t put rules around empty table cells. The old trick to fix this was to put an &nbsp; element in each empty cell. The modern way is to set the cell’s style property border.