Tables in HTML

This tutorial introduces the concept of table and analizes its structure and some of its most basic properties. It focuses essentially on tables' aspects that are used regularly in the development of documents.

Concept

A table is nothing but a means of arranging data in rows and columns. This concept has been present in our society for a long time and has been adopted by HTML in its early stages, as a way to convey information that might otherwise not be obvious or readily understood.

In HTML documents a table can be considered, in a simple way, as a group of rows containing each a group of cells. This is conceptually different to a group of columns containing a group of cells, and this difference will have some impact in the composition and behavior of the table.

Like many other structures in HTML, tables are constructed using elements. In particular, a basic table can be declared using three elements, namely, table (the main container), tr (representing the rows, containers for cells) and td (representing plain cells). Let's make it clear with an example:

<table class="egt">
  <tr>
    <td>Cell 1</td>
    <td>Cell 2</td>
    <td>Cell 3</td>
  </tr>
  <tr>
    <td>Cell 4</td>
    <td>Cell 5</td>
    <td>Cell 6</td>
  </tr>
</table>
Cell 1 Cell 2 Cell 3
Cell 4 Cell 5 Cell 6

Note that this table has been formatted usign CSS to improove comprehension and readability. Authors shouldn't expect these results in tables with no presentational properties assigned.

You can clearly see, in the previous example, the concept of rows containing cells we talked about before. Here it becomes evident how cells, that have been numbered according to their position in the code, follow a sequence in the representation that goes from left to right, one row at a time. This will have further implications, specially when it comes to cell spanning and grouping.

Header cells

Now that the basic structure of a table has been treated, it's time to start making more useful tables.

A header cell is a special type of cell used to organize and categorize other cells in the table. Having said this, it's hard to imagine a table where a header cell wouldn't be of use. Almost any table can benefit from a well placed group of header cells.

In the following example, we're building a table to display information about the weather in the upcoming days. Here, the header cells, represented by the th element, are placed in the first row of the table, on top of the regular cells.

<table class="egt">
  <tr>
    <th>Today</th>
    <th>Tomorrow</th>
    <th>Friday</th>
  </tr>
  <tr>
    <td>Sunny</td>
    <td>Mostly sunny</td>
    <td>Partly cloudy</td>
  </tr>
  <tr>
    <td>19°C</td>
    <td>17°C</td>
    <td>12°C</td>
  </tr>
  <tr>
    <td>E 13 km/h</td>
    <td>E 11 km/h</td>
    <td>S 16 km/h</td>
  </tr>
</table>
Today Tomorrow Friday
Sunny Mostly sunny Partly cloudy
19°C 17°C 12°C
E 13 km/h E 11 km/h S 16 km/h

It's easy to see here how each header cell in the table, provides information for the rest of the cells in the column it belongs to. Some agents, like voice browsers, make the same analysis when it comes to inform the user what header is associated to a particular cell. But in some situations, ambiguities need to be avoided and that's why HTML provides some attributes like scope.

The scope attribute

The scope attribute provides a mechanism to state explicitly what cells a header is affecting. This attribute can only be declared in a header cell and take the values "col", "row", "colgroup" and "rowgroup". The values "col" and "row" indicate that the header cell is providing header information for the rest of the cells in the column or row (respectively) its located at. The other two values will make more sense in coming sections of this tutorial.

In the following example, the table presented before has been improoved with more header cells, in order to enhance readability. Here, the cell in the top-left corner of the table, would provide ambiguous header information if the attribute scope wasn't present. In other words, it could affect cells in its column, as well as cells in its row. The presence of the attribute scope has made clear that the cells affected by this header are those in the same row.

<table class="egt">
  <tr>
    <th scope="row">Day</th>
    <th>Today</th>
    <th>Tomorrow</th>
    <th>Friday</th>
  </tr>
  <tr>
    <th>Condition</th>
    <td>Sunny</td>
    <td>Mostly sunny</td>
    <td>Partly cloudy</td>
  </tr>
  <tr>
    <th>Temperature</th>
    <td>19°C</td>
    <td>17°C</td>
    <td>12°C</td>
  </tr>
  <tr>
    <th>Wind</th>
    <td>E 13 km/h</td>
    <td>E 11 km/h</td>
    <td>S 16 km/h</td>
  </tr>
</table>
Day Today Tomorrow Friday
Condition Sunny Mostly sunny Partly cloudy
Temperature 19°C 17°C 12°C
Wind E 13 km/h E 11 km/h S 16 km/h

12345Next