Tables
Anyone who's seen a data-heavy report, essay, or study knows how useful tables are for quickly and clearly displaying data. They're incredibly useful in web pages as well, good for laying out information, links, and less semantically, images and even entire pages.
HTML provides a whole family of elements for generating and organizing a table's contents. A table's length may daunt you at first, but once you understand the structure, they're remarkably structured and intuitive.
Table terminology
There's a few terms you should know going into working with tables, those being the cell, the row, the head, and the body of the table. Don't worry if the definitions don't mean much to you right now. They will when I start putting together an example table.
Cell
An individual box in a table is called a cell. There's two kinds of cells in HTML, the standard td
, or Table Data, cell, and the th
, or Table Header, cell, which gives semantic importance to the cells that define each row and column's meaning.
Row
Cells are nested inside rows. These are made using the tr
, or Table Row, element.
Head and body
Optionally, you can define a head and body for your table. Rows are nested inside these, allowing you to semantically separate out header rows from data rows. These also provide extra opportunities to style the table using a stylesheet, if you choose. In the graphic, the orange row is the table head, while the blue rows are the table's body.
The table head is defined with the thead
element, and the table body is defined with tbody
.
Putting together an example table
So before we get ahead of ourselves, let's put together a table piece by piece. Tables, naturally, start with the table
element, and then tr
elements are nested inside of it. My table will have three rows to start with.
<table>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
This still doesn't display anything, however. You'll need cells inside the table for the table to appear. Let's give each row three cells.
<table>
<tr>
<th>Album</th>
<th>Artist</th>
<th>Year</th>
</tr>
<tr>
<td>Beautiful Stakes and Powerpoles</td>
<td>Pine Marten</td>
<td>2002</td>
</tr>
<tr>
<td>Everyone Down Here</td>
<td>Earlimart</td>
<td>2003</td>
</tr>
</table>
In order to give your table borders, extra cell spacing, or color, you'll need to use a stylesheet. Good news is that the table's visuals, from the size of the text to the colors of cells to how text is aligned in each of the cells, are fully customizable. If you haven't already tried out CSS, I'll have a link to a page on styling tables in the Further Reading section of this tutorial. Tables, because they're so plain in basic HTML, are a good place to start learning the basics of CSS.
Anyway, to elaborate on table behavior in text: tables have two dimensions, and markup can only go one way, down your page. As a result, each additional tr
element adds another row to the bottom of the table, and every td
and th
nested inside the tr
s adds another column to the right of the table. If you were to add another td
in each row, this table would extend out to four columns automatically.
<table>
<tr>
<th>Album</th>
<th>Artist</th>
<th>Year</th>
<th>Length</th>
</tr>
<tr>
<td>Beautiful Stakes and Powerpoles</td>
<td>Pine Marten</td>
<td>2002</td>
<td>49 minutes</td>
</tr>
<tr>
<td>Everyone Down Here</td>
<td>Earlimart</td>
<td>2003</td>
<td>33 minutes</td>
</tr>
</table>
In case you're wondering, you don't need to segregate out your th
and td
cells quite like this. You can start off each row with a th
, followed by as many td
cells as you'd like. There's no rules outside of their semantic meaning.
One last bit of table sugar I'd like to introduce involves the use of captions. Bigger tables can look especially daunting, not just to you as the page author, but to the reader. Adding a caption to your table allows you to summarize the table contents in a single sentence, which will appear above the table on the page. Use the caption
element for this. Now, to integrate in a head, body, and caption:
<table>
<caption>Early 2000s Californian indie rock records</caption>
<thead>
<tr>
<th>Album</th>
<th>Artist</th>
<th>Year</th>
</tr>
</thead>
<tbody>
<tr>
<td>Beautiful Stakes and Powerpoles</td>
<td>Pine Marten</td>
<td>2002</td>
</tr>
<tr>
<td>Everyone Down Here</td>
<td>Earlimart</td>
<td>2003</td>
</tr>
</tbody>
</table>
Don't mind if there's not much of a visual difference when you add in the thead
and tbody
. Remember that HTML describes the meaning of content, not how it looks visually. That's the job of a stylesheet.
Here, because we've been looking at very plain tables throughout this section, why don't we look at a styled one quick?
colspan
, rowspan
, and the effects of unequal numbers of cells
One final thing to note in laying out your table are the colspan
and rowspan
attributes. With these, you can have a cell take up multiple adjacent rows or columns. This is good if you have data that's joined across two categories, or you'd like to give extra headings to separate out sections of the table.
To give you an example I use on my own site, I have a page of best times for courses in Mario Kart Wii. Each course (and successful time trial) gets its own row in the table. As each course in the game is further categorized into cups of four courses, to break up the table, I have one row for each cup name with a single cell that gets stretched across the entire width of the table, taking up all columns for that row.
<table>
<thead>
<tr>
<th>Course Name</th>
<th>My Time</th>
<th>Expert Time</th>
<th>Bike Used</th>
<th>Date Set</th>
</tr>
</thead>
<tbody>
<tr>
<th colspan="5">Mushroom Cup</th>
</tr>
<tr>
<td>Luigi Circuit</td>
<td><strong>01:19.089</strong></td>
<td>01:19.419</td>
<td>Bullet Bike</td>
<td>01/05/20</td>
</tr>
<tr>
<td>Moo Moo Meadows</td>
<td><strong>01:25.313</strong></td>
<td>01:25.909</td>
<td>Bullet Bike</td>
<td>01/22/20</td>
</tr>
</tbody>
</table>
Here's where you can potentially confuse yourself: the total number of columns in the row must still be equal with the other rows. In other words, if you have a cell that spans two columns, that cell now counts as two td
elements, and you'll have to remove one of the others. If you don't, one of your cells will stick out of the table, and data will potentially be in the wrong spots in the table. In the case of this table, there's five columns, and a cell spanning two columns, plus four more would make for six places—one too many!
If you end up with weird visual errors, just remember to count the number of cells in each row and make sure they equal the same number of columns. A cell spanning three columns counts as three cells.
Summary:
- Tables are excellent for organizing data quickly and clearly on a page.
- In HTML, tables are represented by nests of elements. Rows (
tr
) go inside thetable
, and cells (td
for data cells andth
for header cells) go inside the rows. - Optionally, tables can also have a head and body, represented by
thead
andtbody
, respectively.- Rows nested inside the
thead
element are semantically treated as header rows, giving meaning to each column, and rows nested inside thetbody
element are the data points themselves.
- Rows nested inside the
- Tables can also have an optional
caption
element for summarizing the table's contents. This summary will be displayed above the table on the page. - The number of columns in the table is determined by the row with the largest number of cells.
- This can create visual errors if one row has more cells than the rest of the rows, as most of the rows will appear with blank spaces at the end of them.
- You can make a single cell take up multiple rows and columns using the
rowspan
andcolspan
attributes.- A table cell with a
colspan
of "3" will take up three columns. - If that cell is part of a table with five columns, you'll need to remove two of the other cells in that row. Otherwise, the table will display wrong and data will be in the wrong cells.
- A table cell with a