Web accessibility tutorials Guidance on how to create websites that meet WCAG
Jump to the navigation

Multi-level Tables

Status (not ready for review) -

This is an in-progress, unapproved editor’s draft. Content may change at any time without notice. Please send any suggestions, edits, or comments to the publicly-archived list: wai-eo-editors@w3.org.

Multi-level tables are those that have a structure that is too complex to support strict horizontal or vertical association between header and data cells. In each case, the relationship between header and data cells needs to be defined by giving each <th> cell a unique id attribute, and each <td> a headers attribute that lists related id values, without any comma separation. Table structures that need to be marked up this way include:

  • Where column headers are repeated or changed part-way through the table;
  • Those with three or more header cells related to each data cell;
  • Where some of the header cells aren't in direct horizontal or vertical alignment to related data cells.

Example 1: Table with multiple column headers in each column

This table shows contact details for six suppliers. To avoid producing an overly wide table the first row has <th> cells identifying the first three supply firms and the fourth row has the <th> cells identifying the other three. To ensure that data cells are associated with the correct firm, each <th> cell has a unique id and each <td> cell has a headers attribute listing the id values that relate to it.

Example
Supplier contacts
  Example1 Ltd Example2 Co Example 3 Inc
Contact James Phillips Marie Beauchamp Andrew Bruce
Position Sales Director Sales Manager Client Support Officer
Email jp@example1.co.uk marie@example2.co.fr sales@example3.com
  Example 4 Ltd Example 5Inc Example 6 Co
Contact Suzette Jones Alex Howe Axel Gaunt
Position Sales Officer Sales Director Proprietor
Email Suz@example4.co.uk howe@example5.com sales@example6.co.eu
Code snippet: Assigning id attributes to <th> cells
[…]
<th id="co1">Example1 Ltd</th>
<th id="co2">Example2 Co</th>
[…]
<th id="c1">Contact</th>
[…]
Code snippet: Assigning header attributes to <td> cells
[…]
<td headers="co1 c1">James Phillips</td>
<td headers="co2 c1">Marie Beauchamp</td>
[…]

Full code for Example 1: Table with multiple column headers in each column (new window)

This example shows availability of accommodation of a given type and size in two different locations. For the data to be understood, each <td> cell needs to be associated to three <td> cells (location, size and type of accommodation). To define these complex associations, each <th> cell has a unique id attribute and all data cells have a headers attribute listing the related cell id values.

Example
Availability of holiday accommodation
Studio Apt Chalet Villa
Paris
1 bedroom 11 20 25 23
2 bedroom - 43 52 32
3 bedroom - 13 15 40
Rome
1 bedroom 13 21 22 3
2 bedroom - 23 43 30
3 bedroom - 16 32 40
Code snippet: Assigning id attributes to <th> cells
[…]
	<th id="par" colspan="5" scope="colgroup">Paris</th>
</tr>
<tr>
	<th id="pbed1">1 bedroom</th>
[…]
Code snippet: Assigning header attributes to <td> cells
[…]
<td headers="par pbed1 stud">11</td>
<td headers="par pbed1 apt"> 20</td>
[…]

Full code for Example 2: Table with three headers related to each data cell (new window)

The following WCAG 2.0 technique was used in the examples above: