Tables
A table suits data that has rows and columns: a timetable, a price list, a plan comparison. In HTML a table is built row by row: first a row, then the cells inside it from left to right.
A simple table
<table> is the whole table, <tr> (table row) is a row, <td> (table data) is a regular cell and <th> (table header) is a header cell:
<table>
<tr>
<th>Drink</th>
<th>Price</th>
</tr>
<tr>
<td>Tea</td>
<td>$3</td>
</tr>
<tr>
<td>Coffee</td>
<td>$4</td>
</tr>
</table>The browser made the headers bold and centred them. There are no borders by default.
Borders
Borders are added in CSS. The border-collapse: collapse property merges neighbouring borders into a single line:
<style>
table { border-collapse: collapse; }
th, td { border: 1px solid #999; padding: 6px 12px; }
</style>
<table>
<tr><th>Drink</th><th>Price</th></tr>
<tr><td>Tea</td><td>$3</td></tr>
<tr><td>Coffee</td><td>$4</td></tr>
</table>Without border-collapse every cell would have its own border, and the lines would be doubled.
Table sections
The rows of a large table are split into groups: <thead> is the header, <tbody> is the data, <tfoot> is the totals. <caption> is the table title; it goes first inside <table>:
<style>
table { border-collapse: collapse; }
th, td { border: 1px solid #999; padding: 6px 12px; }
</style>
<table>
<caption>Order #42</caption>
<thead>
<tr><th>Item</th><th>Amount</th></tr>
</thead>
<tbody>
<tr><td>Cappuccino</td><td>$4</td></tr>
<tr><td>Croissant</td><td>$3</td></tr>
</tbody>
<tfoot>
<tr><th>Total</th><td>$7</td></tr>
</tfoot>
</table>Groups help both people and the browser: for example, when a long table is printed, the header repeats on every page.
Merging columns
The colspan attribute stretches a cell across several columns:
<style>
table { border-collapse: collapse; }
th, td { border: 1px solid #999; padding: 6px 12px; }
</style>
<table>
<tr><th colspan="2">Contacts</th></tr>
<tr><td>Phone</td><td>+1 202 555 0123</td></tr>
<tr><td>Email</td><td>hello@example.com</td></tr>
</table>Merging rows
rowspan stretches a cell down across several rows. In the following rows that cell is not written again — its place is taken:
<style>
table { border-collapse: collapse; }
th, td { border: 1px solid #999; padding: 6px 12px; }
</style>
<table>
<tr><th rowspan="2">Monday</th><td>10:00 — yoga</td></tr>
<tr><td>18:00 — swimming</td></tr>
<tr><th>Tuesday</th><td>12:00 — tennis</td></tr>
</table>Common mistake
Tables are for data, not for arranging page blocks into columns. Sites used to be built that way, but such markup is hard to change and does not fit on a phone screen. Layout is done in CSS — with flexbox and grid from the Page layout chapter. Another mistake is a different number of cells in different rows: the table falls apart. Count the cells, taking colspan into account.