What is the best way to code HTML table with multiple headers in between rows? I have created a decent HTML table. However, when I try to use the screen reader for 508 compliance, the screen reader reads all row headers (Header 1, Header 2, header 3) when I navigate through each row. Is there a way to avoid it? What am I missing?
Here is the fiddle:
https://jsfiddle.net/kq739m28/
<p>Test</p>
<div style=" overflow-x: auto;">
<table style=" width: 100%;">
<thead>
<tr>
<td> </td>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
</tr>
</thead>
<tbody>
<tr>
<th colspan="10" scope="colgroup" style=" background-color: #e0e0e0; text-align: left;">Header1</th>
</tr>
<tr>
<th style=" font-weight: 400; text-align: left;">dffddf</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td> </td>
<td> </td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<th style=" font-weight: 400; text-align: left;">fdfdfdf</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<th style=" font-weight: 400; text-align: left;">dffddf</th>
<td align="center" style=" text-align: center; color: black;"> </td>
<td align="center" style=" text-align: center; color: black;"> </td>
<td align="center" style=" text-align: center; color: black;"> </td>
<td align="center" style=" text-align: center; color: black;"> </td>
<td align="center" style=" text-align: center; color: black;"> </td>
<td>✓</td>
<td align="center" style=" text-align: center; color: black;"> </td>
<td align="center" style=" text-align: center; color: black;"> </td>
<td align="center" style=" text-align: center; color: black;"> </td>
</tr>
<tr>
<th colspan="10" scope="colgroup" style=" background-color: #e0e0e0; text-align: left;">Header2</th>
</tr>
<tr>
<th style=" font-weight: 400; text-align: left;">5455445</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td align="center" style=" text-align: center; color: black;"> </td>
<td align="center" style=" text-align: center; color: black;"> </td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<th style=" font-weight: 400; text-align: left;">fdfggfgf</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<th colspan="10" scope="colgroup" style=" background-color: #e0e0e0; text-align: left;">Header3</th>
</tr>
<tr>
<th style=" font-weight: 400; text-align: left;">fgggf</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td> </td>
<td>✓</td>
</tr>
<tr>
<th style=" font-weight: 400; text-align: left;">fgggfgf</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td> </td>
<td> </td>
<td>✓</td>
<td> </td>
</tr>
</table>
</div>
CodePudding user response:
You'll need to use the ARIA role="rowgroup"
attribute on separate <tbody>
elements to specify the group of rows to which the header row must apply. Then you should also apply the scope="rowgroup"
attribute to your individual header rows.
For example:
<table style="width: 100%;">
<thead>
<tr>
<td> </td>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
</tr>
</thead>
<tbody role="rowgroup">
<tr>
<th colspan="10" scope="rowgroup" style="background-color: #e0e0e0; text-align: left;">Header1</th>
</tr>
<tr>
<th>dffddf</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td> </td>
<td> </td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<th>fdfdfdf</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<th>dffddf</th>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>✓</td>
<td> </td>
<td> </td>
<td> </td>
</tr>
</tbody>
<tbody role="rowgroup">
<tr>
<th colspan="10" scope="rowgroup" style=" background-color: #e0e0e0; text-align: left;">Header2</th>
</tr>
<tr>
<th>5455445</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td> </td>
<td> </td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<th>fdfggfgf</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
</tbody>
<tbody role="rowgroup">
<tr>
<th colspan="10" scope="rowgroup" style=" background-color: #e0e0e0; text-align: left;">Header3</th>
</tr>
<tr>
<th>fgggf</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td> </td>
<td>✓</td>
</tr>
<tr>
<th>fgggfgf</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td> </td>
<td> </td>
<td>✓</td>
<td> </td>
</tr>
</tbody>
</table>
I tested this code in Chrome 99 with JAWS 2022 and NVDA 2021 to make sure that the screen reader wasn't announcing all row headers each time I moved from column to column.
Here are some useful articles explaining how to implement the ARIA rowgroup
role:
MDN Web Docs: ARIA: rowgroup role
CodePudding user response:
You can make the screen reader skip it.
Methods to Hide from Screen Readers: To hide text from a screen reader and display it visually, use the
aria-hidden attribute
and set it to true. Source from Pluralsight
<p aria-hidden="true">Visible text screen readers should ignore</p>