I have a single table with rows that are grouped, and there should be a header above each group. What is the correct markup for this when it comes to semantics and accessibility?
I’m aware of the scope
attribute for <th>
elements, and I’m thinking the rowgroup
and colgroup
might be related to this, but I don’t understand how to actually apply it properly, or whether the <td>
or <tbody>
elements need some attributes applied to them as well.
Here is an example table, without any accessibility attributes:
table { border-collapse: collapse; text-align: center }
thead { background: #ccc }
th, td { padding: 0.25em 0.5em; border: 1px solid #ddd }
tbody th { background: #eee }
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
</tr>
</thead>
<tbody>
<tr>
<th colspan="3">Group 1</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</tbody>
<tbody>
<tr>
<th colspan="3">Gruppe 2</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</tbody>
<tbody>
<tr>
<th colspan="3">Gruppe 3</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</tbody>
</table>
2
Answers
scope="rowgroup"
would be the correct markup.You already did a great job and used several
<tbody>
elements to group rows.The HTML Spec mentions for
rowgroup
:So how exactly does one mark up a row group?
ARIA in HTML mentions that the the default element for the
rowgroup
role is<tbody>
, as it’s already used in the question.The next question, then, is how browsers and screen readers actually expose this rowgroup. For concepts like
section
roles, the boundaries are announced, so when you navigate inside a new group, its name is announced.rowgroup
is derived fromsection
, so this behaviour would seem appropriate as well.I doubt that a lot of screen readers actually announce this. I will look into this, if anybody has results to share already, that would be great.
You have divided the data into row groups with
tbody
elements.Use
scope="rowgroup"
on theth
element to apply that header only to the remaining data of the same row group.Or (as very verbose alternative), explicitly associate headers to data cells by listing each header by its ID in the data cell’s
headers
attribute.Row group headers apply to all remaining data cells in the same row group, where "remaining" means: The cells whose slots’ x- and y-coordinates are greater than or equal to the header’s slots’.
Or in other words: All cells that are part of the rectangle bounding the header cell and the row group’s ‘highest’ slot (where ‘highest’ means: hightest x- and y-coordinate); the row group’s slot in the bottom-right corner (in left-to-right top-to-bottom writing direction).
Section 4.9.10 The
th
element of the HTML specification contains a note showing which headers apply to which slots, including row group headers. For visual reference, see the bright-green branching arrows:Or see this interactive table which highlights all affected cells for a clicked header: