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 enclose 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).

Style

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

Generally, 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.

Style sheets have become the standard means of specifying the spacing and widths of table cells, and borders drawn between them — replacing many table attributes of older versions of HTML.

Styling has also changed the use of tables in HTML. In HTML 3, tables were the only means of providing horizontal alignment in a web page, but modern styles can take over much of this purely presentational 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 mileage may vary.

As always with CSS, it is usually preferred to place style directives in the head block of the HTML code, to separate presentation from content. In the examples that follow therefore, a bit of CSS style will be shown, and then the HTML code that it refers to.

Borders

In the old days, table frames and cell borders were handled by attributes of the table. This was tricky, and less flexible than the modern CSS styling methods.

These days, borders of the table and its cells are specified by CSS border values. If the border value is "0", no borders are drawn. The CSS border-left specifies the border to be drawn on the left side, etc. If its value is thin black solid, a thin line border is drawn. There is a variety of border styles besides solid.

Building on the previous example, with the style

	table#Ex0 { border: medium black ridge; }
	#Ex0 th { border: 0; }
	#Ex0 td { border: thin black solid; }

the code

	<table id="Ex0">
	<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 CSS border-spacing value that matches the table tag. The padding between the contents of the table cells and the border of the table cells is adjusted by the CSS padding value.

Once again building on the previous example, with the style

	table#Ex1, #Ex1 td, #Ex1 th { border: thin black solid; }

the code

	<table id="Ex1">
	<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 with the style

	table#Ex2 { border: thin black solid; padding-top: 8pt; border-spacing: 4pt; }
	#Ex2 td, #Ex2 th { border: thin black solid; }

the code

	<table id="Ex2">
	<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

To make a tight table whose cell contents are adjacent, set the border-collapse value for the table to collapse. With the styles

	table#Ex3, #Ex3 td, #Ex3 th { border: thin black solid; }
	table#Ex3 { border-collapse: collapse; }

this code

	<table id="Ex3">
	<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.

Cells that span 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, with the styles

	table#Ex4, #Ex4 td, #Ex4 th { border: thin black solid; }

this code

	<table id="Ex4">
	<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 rowspan greater than zero, it displaces the cells in its column in the row below it. So in those rows, no td tags should be inserted for that column. In the above example, there are no cells “B one” or “C one”.

Likewise, if a cell has a colspan greater than zero, it displaces the cells in its row in the columns to its right. So for those columns, no td tags should be present. 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, changed in the transition from HTML version 3 to 4, and then again in version 5. What is now considered to be the correct method may not be recognized by older browsers; the older methods will not validate as correct HTML.

You can specify the width of a table by using the CSS width property of the table. Its value can be specified by various measurements, including an absolute physical width (not usually recommended), a percentage of the width of the element that contains it, or a width relative to some other measure, such as the font height.

In HTML 3, the table tag had a width attribute, which could be either an absolute pixel width, or a percentage of the width of the containing element. This attribute is no longer valid HTML.

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

The modern 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 result in a centered table.

To put that together, consider this example

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

which is 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.

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 the color of a whole row can be specified 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 since HTML 4 with the colgroup and col tags. These allow formatting styles to be specified 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 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.

Here is an example showing each of these features. With the styles

	table#Ex5 { border: thin black solid; }
	#Ex5 tbody td { border: thin black solid; }
	#Ex5 tbody th { border-right: medium black solid; }
	#Ex5 thead th { border-bottom: medium black solid; }

this code

	<table id="Ex5">
	<caption> a table caption </caption>
	<colgroup> <col /> <col /> </colgroup>
	<colgroup> <col style="background-color: orange;" /> </colgroup>
	<colgroup> <col /> </colgroup>
	<thead>
	<tr><td></td><th>one</th><th>two</th><th>three</th></tr>
	</thead>
	<tbody>
	<tr><th>A</th><td>A one</td><td>A two</td><td>A three</td></tr>
	<tr><th>B</th><td>B one</td><td>B two</td><td>B three</td></tr>
	<tr><th>C</th><td>C one</td><td>C two</td><td>C three</td></tr>
	</tbody>
	</table>
	

is rendered as

a table caption
onetwothree
AA oneA twoA three
BB oneB twoB three
CC oneC twoC three

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.