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 one | header two |
|---|---|
| data one | data two |
| data three | data 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 one | header two |
|---|---|
| data one | data two |
| data three | data 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 one | header two |
|---|---|
| data one | data two |
| data three | data 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 one | A two | A three |
| B two | B 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
| header one | header two |
|---|---|
| data one | data two |
| data three | data 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 element
in each empty cell. The modern way is to set the cell’s style property
border.