I'm doing some accessibility work and had a request to augment our current tables to add attributes of scope="col" and scope="row to existing code. I was looking at some documentation here:
https://www.w3.org/TR/WCAG20-TECHS/H63.html
and this has me now mixing th and td tags within a tr. Is this allowed/correct?
Yes, that's perfectly valid from an HTML perspective and it creates a better accessible experience for assistive technology users because the tech knows whether a cell is a table header and specifically knows if it's a row or column header.
For column headers, you typically have all the <th scope="col">
elements in the same <tr>
(although you don't have to) because you are defining the column headers.
<tr>
<th scope="col">col1</th>
<th scope="col">col2th>
<th scope="col">col3</th>
</tr>
For row headers, that's where you'd typically mix <th>
and <td>
elements in the same <tr>
. You have to decide which cell in a row should be the "label" for that row. It's often the first cell in the row so the first element in the <tr>
would be a <th scope="row">
and all the remaining elements would be <td>
.
<tr>
<th scope="row">row1 label</th>
<td>data cell 2</td>
<td>data cell 3</td>
</tr>
<tr>
<th scope="row">row2 label</th>
<td>data cell 2</td>
<td>data cell 3</td>
</tr>
But it doesn't have to be the first cell in the row. I've seen examples (and written some myself) where the 3rd or 4th cell in the row should be the label, in which case my <tr>
would have a few <td>
elements and then the <th scope="row">
and then the remaining <td>
elements.
<tr>
<td>data cell 1</td>
<td>data cell 2</td>
<th scope="row">row1 label</th>
<td>data cell 4</td>
</tr>
<tr>
<td>data cell 1</td>
<td>data cell 2</td>
<th scope="row">row2 label</th>
<td>data cell 4</td>
</tr>
Just make sure you always use the same cell in the row as the label for each row. (Ignoring grouped row labels for now, which is more complicated). That is, if the 3rd cell in the <tr>
is a <th>
, then make sure the 3rd cell for all the rows is a <th>
.
Note that some screen readers might not announce the row header (<th scope="row">
) for any data cells to the left of the header if the row header is not the first cell in the row. That's a bug with the screen reader.