Search code examples
htmlaccessibilitynvda

Accessibility with multiple <tbody> tags in a table


I have multiple <tbody> sections in my <table> and it's reading each <th> tag the table contains. They have unique id and header attributes assigned to the various th and td tags so, to me, it doesn't make sense why the NVDA screen reader is outputting the following output:

[row# tbody 1, column header 1 name]
[<th> tbody 2, column header 1 name]
[<th> tbody 3, column header 1 name]
Current tbody 4, column header 1 name
[output of column1 data]
[output of column2 data]
[output of column3 data]
[output of column4 data]

The HTML is structured like this, here is the Pen also showing this issue

caption{
  text-align:left;
  display: table-caption;
  clip: rect(1px, 1px, 1px, 1px);
  height:1px;
  overflow:hidden;
  position: absolute;
  top: auto;
  width: 1px;
}
.left{
  text-align:left;
}
.right{
  text-align:right;
}
.hierarchy1{
  font-size:1.25em;
  font-weight:bold;
}
.hierarchy2{
  backgound-color:#ededed;
  padding: 9px 10px 7px 8px;
  border-top: 1px solid #ccc;
  font-weight: bold;
}
.hierarchy3{
}
tr{
  height:45px;
  display:table-row;
}
table
{
  width: 100%;
  border-collapse: collapse;
}
<table>
  <caption class="offScreen">Balance Sheet Table</caption>
  <tbody>
  <tr class="hierarchy0 bold">
    <th class="left" scope="col" id="date-cell-0-1">Assets (Millions)</th>
    <th class="right greyBL" scope="col" id="date-cell-1-1">9/30/2012</th>
    <th class="right greyBL" scope="col" id="date-cell-2-1">9/30/2013</th>
    <th class="right greyBL" scope="col" id="date-cell-3-1">9/30/2014</th>
    <th class="right greyBL" scope="col" id="date-cell-4-1">9/30/2015</th>
  </tr>
  <tr class="hierarchy5">
    <td class="left" headers="date-cell-0-1">Cash</td>
    <td class="right" headers="date-cell-1-1">--</td>
    <td class="right" headers="date-cell-2-1">--</td>
    <td class="right" headers="date-cell-3-1">10,232.00</td>
    <td class="right" headers="date-cell-4-1">--</td>
  </tr>
  <tr class="hierarchy4">
    <td class="left" headers="date-cell-0-1">Cash Equivalents</td>
    <td class="right" headers="date-cell-1-1">10,746.00</td>
    <td class="right" headers="date-cell-2-1">14,259.00</td>
    <td class="right" headers="date-cell-3-1">13,844.00</td>
    <td class="right" headers="date-cell-4-1">21,120.00</td>
  </tr>
  </tbody>
 <tbody>
  <tr class="hierarchy0 bold">
    <th class="left" scope="col" id="date-cell-0-2">Liability And Shareholder Equity (Millions)</th>
    <th class="right greyBL" scope="col" id="date-cell-1-2">9/30/2012</th>
    <th class="right greyBL" scope="col" id="date-cell-2-2">9/30/2013</th>
    <th class="right greyBL" scope="col" id="date-cell-3-2">9/30/2014</th>
    <th class="right greyBL" scope="col" id="date-cell-4-2">9/30/2015</th>
  </tr>
  <tr class="hierarchy5">
    <td class="left" headers="date-cell-0-2">Accounts Payable</td>
    <td class="right" headers="date-cell-1-2">21,175.00</td>
    <td class="right" headers="date-cell-2-2">22,367.00</td>
    <td class="right" headers="date-cell-3-2">30,196.00</td>
    <td class="right" headers="date-cell-4-2">35,490.00</td>
  </tr>
  <tr class="hierarchy4">
    <td class="left" headers="date-cell-0-2">Income Tax Payable</td>
    <td class="right" headers="date-cell-1-2">--</td>
    <td class="right" headers="date-cell-2-2">--</td>
    <td class="right" headers="date-cell-3-2">--</td>
    <td class="right" headers="date-cell-4-2">--</td>
  </tr>
  </tbody>
  <tbody>
  <tr class="hierarchy0 bold">
    <th class="left" scope="col" id="date-cell-0-3">Supplemental (Millions)</th>
    <th class="right greyBL" scope="col" id="date-cell-1-3">9/30/2012</th>
    <th class="right greyBL" scope="col" id="date-cell-2-3">9/30/2013</th>
    <th class="right greyBL" scope="col" id="date-cell-3-3">9/30/2014</th>
    <th class="right greyBL" scope="col" id="date-cell-4-3">9/30/2015</th>
  </tr>
  <tr class="hierarchy1">
    <td class="right" headers="date-cell-0-3">Total Capitalization</td>
    <td class="right" headers="date-cell-1-3">111,210.00</td>
    <td class="right" headers="date-cell-2-3">140,509.00</td>
    <td class="right" headers="date-cell-3-3">140,534.00</td>
    <td class="right" headers="date-cell-4-3">172,818.00</td>
  </tr>
  <tr class="hierarchy1">
    <td class="left" headers="date-cell-0-3">Capital Lease Obligations</td>
    <td class="right" headers="date-cell-1-3">--</td>
    <td class="right" headers="date-cell-2-3">--</td>
    <td class="right" headers="date-cell-3-3">--</td>
    <td class="right" headers="date-cell-4-3">--</td>
  </tr>
  <tr class="hierarchy1">
    <td class="left" headers="date-cell-0-3">Preferred Stock Equity</td>
    <td class="right" headers="date-cell-1-3">--</td>
    <td class="right" headers="date-cell-2-3">--</td>
    <td class="right" headers="date-cell-3-3">--</td>
    <td class="right" headers="date-cell-4-3">--</td>
  </tr>
  </tbody>

If you have any insight to this HTML structure and accessibility, it would be much appreciated.


Solution

  • Through the comments, I found this issue is related to Chrome w/ NVDA. Firefox w/ NVDA works as expected.

    To work cross browser w/ NVDA, I built multiple tables, one for each th, and removed the headers and id attributes because it makes more semantic sense to do so. Here's an example of it working cross browser (Chrome, Firefox) with NVDA

    <table>
      <caption class="offScreen">Balance Sheet Table</caption>
      <tbody>
      <tr class="hierarchy0 bold">
        <th class="left" scope="col">Assets (Millions)</th>
        <th class="right greyBL" scope="col">9/30/2012</th>
        <th class="right greyBL" scope="col">9/30/2013</th>
        <th class="right greyBL" scope="col">9/30/2014</th>
        <th class="right greyBL" scope="col">9/30/2015</th>
      </tr>
      <tr class="hierarchy5">
        <td class="left">Cash</td>
        <td class="right">--</td>
        <td class="right">--</td>
        <td class="right">10,232.00</td>
        <td class="right">--</td>
      </tr>
      <tr class="hierarchy4">
        <td class="left">Cash Equivalents</td>
        <td class="right">10,746.00</td>
        <td class="right">14,259.00</td>
        <td class="right">13,844.00</td>
        <td class="right">21,120.00</td>
      </tr>
      </tbody>
    </table>
    <table>
     <tbody>
      <tr class="hierarchy0 bold">
        <th class="left" scope="col">Liability And Shareholder Equity (Millions)</th>
        <th class="right greyBL" scope="col">9/30/2012</th>
        <th class="right greyBL" scope="col">9/30/2013</th>
        <th class="right greyBL" scope="col">9/30/2014</th>
        <th class="right greyBL" scope="col">9/30/2015</th>
      </tr>
      <tr class="hierarchy5">
        <td class="left">Accounts Payable</td>
        <td class="right">21,175.00</td>
        <td class="right">22,367.00</td>
        <td class="right">30,196.00</td>
        <td class="right">35,490.00</td>
      </tr>
      <tr class="hierarchy4">
        <td class="left">Income Tax Payable</td>
        <td class="right">--</td>
        <td class="right">--</td>
        <td class="right">--</td>
        <td class="right">--</td>
      </tr>
      </tbody>
     </table>
     <table>
      <tbody>
      <tr class="hierarchy0 bold">
        <th class="left" scope="col">Supplemental (Millions)</th>
        <th class="right greyBL" scope="col">9/30/2012</th>
        <th class="right greyBL" scope="col">9/30/2013</th>
        <th class="right greyBL" scope="col">9/30/2014</th>
        <th class="right greyBL" scope="col">9/30/2015</th>
      </tr>
      <tr class="hierarchy1">
        <td class="right">Total Capitalization</td>
        <td class="right">111,210.00</td>
        <td class="right">140,509.00</td>
        <td class="right">140,534.00</td>
        <td class="right">172,818.00</td>
      </tr>
      <tr class="hierarchy1">
        <td class="left">Capital Lease Obligations</td>
        <td class="right">--</td>
        <td class="right">--</td>
        <td class="right">--</td>
        <td class="right">--</td>
      </tr>
      <tr class="hierarchy1">
        <td class="left">Preferred Stock Equity</td>
        <td class="right">--</td>
        <td class="right">--</td>
        <td class="right">--</td>
        <td class="right">--</td>
      </tr>
      </tbody>