thoughts
[HTML] the table element
2005-07-06
In this article I discuss the use of the table element. This element is well known by almost every developer, but often misused for layout purposes. Articles about this can be found throughout the entire net nowadays, but I like to stress again that replacing table elements by div elements for layout purposes is generally not a good idea. Also see this article about the use of div. When a table is used for the purpose it was invented for (displaying tabular data), lots of things are often forgotton.
The use of rowgroups
Let's have a look at a typical table, containing the data of some people. I will use this data throughout the article and refine the HTML step by step. I will not add source code for every table, but only the relevant parts, so keep the source of this document along if you want.
| Id | First Name | Last Name | Salary |
| 1 | Todd | Ryker | 2100 |
| 2 | Bob | Rose | 2500 |
| total costs | 4600 |
And the source code of this table:
<table>
<tr>
<td>Id</td>
<td>First Name</td>
<td>Last Name</td>
<td>Salary</td>
</tr>
<tr>
<td>1</td>
<td>Todd</td>
<td>Ryker</td>
<td>2100</td>
</tr>
<tr>
<td>2</td>
<td>Bob</td>
<td>Rose</td>
<td>2500</td>
</tr>
<tr>
<td>total costs</td>
<td></td>
<td></td>
<td>4600</td>
</tr>
</table>
As you can see in this table, not all rows have the same meaning; the top row contains some headers for the columns, the next to rows are actual data and the bottom row contains totals. You could specify this difference with thead, tfoot and tbody elements as follows:
<table>
<thead>
...
</thead>
<tfoot>
...
</tfoot>
<tbody>
...
</tbody>
</table>
As you probably noticed, the tfoot element is in front of the tbody element. In case of large tables, this ensures the footer can be rendered before all body data is loaded.
This changes a little of the table's appearance, but that's just because I've put some css rules on tfoot in my stylesheet (note that you can use the extra elements nicely this way). Per default it does not have any visual effect. (check this page without styles for instance)
| Id | First Name | Last Name | Salary |
| total costs | 4600 | ||
| 1 | Todd | Ryker | 2100 |
| 2 | Bob | Rose | 2500 |
Table header cells and caption
As I already mentioned, the top row (now in a thead element) contains headers for the columns below it. Furthermore, the leftmost cell in the footer also functions as a header cell. For normal table data cells we have the td element as I assume you know, but for header cells we have the th element. th can appear anywhere in the table, not just in the thead. Adding these changes our appearance a little more, just because I added some CSS rules for th as well. Default rendering is also al little different (try to disable styles if you use firefox or opera).
A table often has a caption applied to it, this can be done using the caption element. Which must appear as the first element within the table.
| Id | First Name | Last Name | Salary |
|---|---|---|---|
| total costs | 4600 | ||
| 1 | Todd | Ryker | 2100 |
| 2 | Bob | Rose | 2500 |
Lots of attributes
There's several attributes you can add to tie things semantically together. I you wonder about the benefit of all this, just read some more about semantics, because that's what HTML is all about in the end.
The scope attribute
The scope attribute is used to define the scope of header cells (th). It can be one of the following values:
- col
- colgroup
- row
- rowgroup
The top four headers should all have scope="col", because they all say something about the column below. The header in the foot however should have scope="row", because it only says something about the row. "rowgroup" is used when a header says something about a complete group of rows (like thead, tfoot or tbody), and "colgroup" is used when a header is about a group of collumns (more on that later).
The headers attribute
As an alternative to the method above, all header cells could be provided with an id and every particular cell (td) could be provided by a headers attribute, containing a space seperated list of header id's. This might be a more usefull method in very complicated tables.
The summary attribute
The table element can be provided with a summary attribute to provide a textual summary for the table. This could be usefull for search engines and user agents that do not support table rendering.
Having said this, here's our table again, now provided with these attributes. Of course, nothing can be seen as a result, but take a look at the source.
| Id | First Name | Last Name | Salary |
|---|---|---|---|
| total costs | 4600 | ||
| 1 | Todd | Ryker | 2100 |
| 2 | Bob | Rose | 2500 |
Grouping columns
We have grouped rows before, and you might have wondered whether there are ways to group columns, well there are. As you can not nest rows and columns together (they cross), columns are added as abstract elements at the top of the table, in our case, it will be something like (omitted some attributes discussed above):
<table>
<caption>Employee Salary</caption>
<col>
<colgroup>
<col>
<col>
</colgroup>
<col>
<thead>...</thead>
<tfoot>...</tfoot>
<tbody>...</tbody>
</table>
Both col and colgroup elements can have a span attribute, indicating the number of collumns it represents. col elements are always empty, colgroup elements may contain zero or more col elements.
These elements can be used to give (groups of) columns an id, or to sepcify some special CSS to these.
For more information on grouping columns, see W3C HTML 4.01: 11.2.4 Column groups: the COLGROUP and COL elements.
Further reading
- The W3C HTML 4.01 spec about tables (recommended)
- The W3C CSS 2.1 spec about tables (pay attention to paragraph 3 with respect to column styling)
- Veerle Pieters' blog about styling tables with CSS
Additional resources (top 15)
Below is a list of additional resources that might contain extra information about the subject at hand. These are all sites linking to this one (i.e. backtracking).
- [CSS] Recordset formatten - Webdesign & Graphics - GoT - Powered by React [nl] (115)
- [CSS] Recordset formatten - Webdesign & Graphics - GoT - Powered by React [nl] (6)
- [CSS] Recordset formatten - Webdesign & Graphics - GoT - Powered by React [nl] (4)
- nest tbody element - Google Search (4)
- [CSS] Recordset formatten - Webdesign & Graphics - GoT - Powered by React [nl] (4)
- nest colgroup rowgroup - Google Search (3)
- [CSS] Recordset formatten - Webdesign, Markup & Clientside Scripting - GoT - Powered by Re... [nl] (2)
- colgroup rowgroup - Căutare Google (2)
- table elements firefox - Google Search (2)
- html rowgroup - Google Search (2)
- Todd Ryker - Google Search (2)
- [CSS] Recordset formatten - Webdesign & Graphics - GoT - Powered by React [nl] (2)
- tbody rowgroup difference - Google Search (2)
- <colgroup for rows - Google Search (2)
- [CSS] Recordset formatten - Webdesign, Markup & Clientside Scripting - GoT - Powered by Re... [nl] (2)
