HTML - Table headers & scope
This describes how to properly create accessible tables with scoped TH cells.
Using this raw table as an example (poor accessibility since no header cells are specified)
<table>
<thead>
<tr>
<td>Col 0, Row 0</td>
<td>Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
</tr>
</thead>
<tbody>
<tr>
<td>Row 1</td>
<td>123</td>
<td>345</td>
<td>567</td>
</tr>
<tr>
<td>Row 2</td>
<td>123</td>
<td>345</td>
<td>567</td>
</tr>
</tbody>
</table>
Col 0, Row 0 | Col 1 | Col 2 | Col 3 |
Row 1 | 123 | 345 | 567 |
Row 2 | 123 | 345 | 567 |
The cells Col 0/1/2/3 and Row 1/2 should all be defined as header cells (i.e., change them from <td> to <th>) to show that they're labels for rows and columns:
<table>
<thead>
<tr>
<th>Col 0, Row 0</th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
</thead>
<tbody>
<tr>
<th>Row 1</th>
<td>123</td>
<td>345</td>
<td>567</td>
</tr>
<tr>
<th>Row 2</th>
<td>123</td>
<td>345</td>
<td>567</td>
</tr>
</tbody>
</table>
Col 0, Row 0 | Col 1 | Col 2 | Col 3 |
---|---|---|---|
Row 1 | 123 | 345 | 567 |
Row 2 | 123 | 345 | 567 |
However there's ambiguity since "Col 0, Row 0" could refer to either the row or the column it's in. (And actually, any of the TH cells could refer to a col or row in complex cases) Adding scope="col" or scope="row" fixes that by specifying what each describes:
<table>
<thead>
<tr>
<th scope="row">Row 0</th>
<th scope="col">Col 1</th>
<th scope="col">Col 2</th>
<th scope="col">Col 3</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Row 1</th>
<td>123</td>
<td>345</td>
<td>567</td>
</tr>
<tr>
<th scope="row">Row 2</th>
<td>123</td>
<td>345</td>
<td>567</td>
</tr>
</tbody>
</table>
Row 0 | Col 1 | Col 2 | Col 3 |
---|---|---|---|
Row 1 | 123 | 345 | 567 |
Row 2 | 123 | 345 | 567 |