Irregular headers
Designing with irregular headers
A table is irregular when one or more of its headers span multiple columns or rows.
HTML introduces attributes and elements dedicated to representing the relationships between these row- or column-spanning headers and the data cells they define.
The scope attribute
When a header spans multiple columns, add the scope="colgroup"
attribute to the <th>
element. See header A in the example table below.
When a header spans multiple rows, add the scope="rowgroup"
attribute to the <th>
element. See header B in the example table below.
For solo column headers, add the scope="col"
attribute to the <th>
element. See headers A1, A2, A3 in the example table below.
For solo row headers, add the scope="row"
attribute to the <th>
element. See headers B1, B2 in the example table below.
Example begins
A | ||||
---|---|---|---|---|
A1 | A2 | A3 | ||
B | B1 | |||
B2 |
Example ends
Screen reader support for the scope="rowgroup"
attribute is worse than support for scope="colgroup"
. When possible, design tables to leverage scope="colgroup"
and avoid scope="rowgroup"
.
View HTML
Code begins
<table class="table table-bordered">
<caption>Table with a column-spanning header and a row-spanning header</caption>
<thead class="bg-primary">
<tr>
<td colspan="2" rowspan="2"> </td>
<th colspan="3" scope="colgroup">A</th>
</tr>
<tr>
<th scope="col">A1</th>
<th scope="col">A2</th>
<th scope="col">A3</th>
</tr>
</thead>
<tbody>
<tr>
<th rowspan="2" class="bg-primary" scope="rowgroup">B</th>
<th class="bg-primary" scope="row">B1</th>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<th class="bg-primary" scope="row">B2</th>
<td> </td>
<td> </td>
<td> </td>
</tr>
</tbody>
</table>
Code ends
The group-defining elements
Irregular tables also define their solo columns and spanning columns with the <col>
and <colgroup>
elements, respectively. These elements are the first children of the table element and are listed in the order the columns appear in the table. The span attribute of the <colgroup>
element holds the number of columns spanned.
Irregular tables define row groups using the <thead>
, <tbody>
and <tfoot>
elements. <tbody>
defines a new row group of rows with each use, while <thead>
and <tfoot>
do as well but can only be used once per table.
Good example: Table with column and row-spanning headers
In this example, "Country" and "Onwership" are solo columns, each identified with a <col>
element. "Scenario" spans columns, identified with a <colgroup span="3">
element. The "Canada" and "USA" headers and their respective rows are each nested in a <tbody>
element.
Example begins
Country | Ownership | Scenario | ||
---|---|---|---|---|
A | B | C | ||
Canada | Purchase | likely | very unlikely | n/a |
Rent | unlikely | very unlikely | very unlikely | |
USA | Purchase | unlikely | very unlikely | very unlikely |
Rent | likely | very likely | n/a |
Example ends
View HTML
Code begins
<table class="table table-bordered">
<col>
<col>
<colgroup span="3"></colgroup>
<caption>Ownership scenarios, Canada vs USA</caption>
<thead>
<tr class="bg-success">
<th scope="col" rowspan="2">Country</th>
<th scope="col" rowspan="2">Ownership</th>
<th scope="colgroup" colspan="3">Scenario</th>
</tr>
<tr class="bg-success">
<th scope="col">A</th>
<th scope="col">B</th>
<th scope="col">C</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="rowgroup" rowspan="2" class="bg-success">Canada</th>
<th scope="row" class="bg-success">Purchase</th>
<td>likely</td>
<td>very unlikely</td>
<td>n/a</td>
</tr>
<tr>
<th scope="row" class="bg-success">Rent</th>
<td>unlikely</td>
<td>very unlikely</td>
<td>very unlikely</td>
</tr>
</tbody>
<tbody>
<tr>
<th scope="rowgroup" rowspan="2" class="bg-success">USA</th>
<th scope="row" class="bg-success">Purchase</th>
<td>unlikely</td>
<td>very unlikely</td>
<td>very unlikely</td>
</tr>
<tr>
<th scope="row" class="bg-success">Rent</th>
<td>likely</td>
<td>very likely</td>
<td>n/a</td>
</tr>
</tbody>
</table>
Code ends