Home > Net >  What is the best way to code HTML table with multiple headers in between rows?
What is the best way to code HTML table with multiple headers in between rows?

Time:04-14

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>&#160;</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>&#160;</td>
        <td>&#160;</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;">&#160;</td>
        <td align="center" style=" text-align: center; color: black;">&#160;</td>
        <td align="center" style=" text-align: center; color: black;">&#160;</td>
        <td align="center" style=" text-align: center; color: black;">&#160;</td>
        <td align="center" style=" text-align: center; color: black;">&#160;</td>
        <td>✓</td>
        <td align="center" style=" text-align: center; color: black;">&#160;</td>
        <td align="center" style=" text-align: center; color: black;">&#160;</td>
        <td align="center" style=" text-align: center; color: black;">&#160;</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;">&#160;</td>
        <td align="center" style=" text-align: center; color: black;">&#160;</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>&#160;</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>&#160;</td>
        <td>&#160;</td>
        <td>✓</td>
        <td>&#160;</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>&#160;</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>&#160;</td>
            <td>&#160;</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>&#160;</td>
            <td>&#160;</td>
            <td>&#160;</td>
            <td>&#160;</td>
            <td>&#160;</td>
            <td>✓</td>
            <td>&#160;</td>
            <td>&#160;</td>
            <td>&#160;</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>&#160;</td>
            <td>&#160;</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>&#160;</td>
            <td>✓</td>
        </tr>
        <tr>
            <th>fgggfgf</th>
            <td>✓</td>
            <td>✓</td>
            <td>✓</td>
            <td>✓</td>
            <td>✓</td>
            <td>&#160;</td>
            <td>&#160;</td>
            <td>✓</td>
            <td>&#160;</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:

W3C Techniques for WCAG 2.1: Using the scope attribute to associate header cells and data cells in data tables

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>
  • Related