Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hidden aria labels in HTML table (for screen reader accessibility)

In my webpage, I need to create a table which has a header row which is visible or hidden according to some user configuration. This table also needs to be fully accessible (specifically, since the table can be very long, I would like that shortcuts that read the row/column headers would work). I only have ChromeVox to test with (I'll detail about behaviors with other readers from blog-posts I found).

My current layout looks similar to this one:

CSS:

.table-header-show {
}

.table-header-hide {
  display: none;
}

HTML:

<table>
  <!-- ${show} is used to choose the right class the user configuration -->
  <thead class="table-header-${show}">
    <tr>
      <th>Name</th>
      <th>Value 1</th>
      <th>Value 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John Doe</td>
      <td>Value 1a</td>
      <td>Value 2a</td>
    </tr>
  </tbody>
</table>

When the header is visible, there is no problem at all. When the header is hidden, it depends on the screen reader whether these labels are read out or not:

  • I would like the header row to be skipped when using regular navigation* with the screen reader, but use the header row to announce column labels
  • With ChromeVox, the first works (skipped in navigation) but the second fails (the hidden row is not used to label columns)
  • Again with ChromeVox, moving the hiding to be declared as astyle attribute rather than a class, cause both desired behaviors to work
  • According to a blog post I found, screen readers somtimes ignore display: none in order to speak out content, and sometimes they do not - so I'm not sure I can rely on this sort of hiding to be reliable for my purpose (hide for navigation, use for labeling)

So, how can I achieve my desired behavior in a cross-browser-reader way?

  • AFAIK, the problem with off-screen/1px-sized hiding (as suggested here) is that if I do this for the header row, then all the column headers would always be read out...
like image 781
Barak Itkin Avatar asked Nov 11 '14 08:11

Barak Itkin


People also ask

How to hide elements from screen readers using Aria?

Hiding elements from screen readers using aria-hidden. ARIA provides an attribute which allows to hide elements from screen readers. It works pretty uniformly on non-focusable elements in modern browsers and screen readers, but it still has some very odd peculiarities. So you better try to create solutions that do not need it.

What is the difference between accessible hiding class and Aria-label?

The accessible hiding class solution still offers an advantage compared to the aria-label solution. If the CSS is disabled (replaced with a custom CSS adapted to a certain disability, for example), the hidden accessibly text will be displayed. This attribute will hide an element (or group of elements) to screen readers.

Does the ARIA-hidden attribute affect the display?

It has however no effect on the display. To hide an element to screen readers (and child elements), simply add the aria-hidden="true" attribute. If you put a focusable element in content (even on a parent node) with `aria-hidden =" true "`, it will be present in keyboard navigation but will be empty for AT.

How do I use aria in HTML?

The first rule of ARIA use is if you can use a native feature with the semantics and behavior you require already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so. Employ the HTML <table> element instead of the ARIA role of table whenever possible.


1 Answers

The most fool proof option will be to hide the header rows from the screen reader, either by removing them from the DOM (preferred) or with a screen-reader safe removal. Then insert the header into each applicable cell with text-indent: -999em; or similar visual hiding that preserves screen reader access.

This is a very unsatisfying answer, but it should be tenable with the jquery. Roughly: for each th, store content in an array, then select each td in the applicable column, and .prependTo() the 'th'.

Again, very unsatisfying and messy but the only fool proof solution I can think of. Best of luck.

like image 189
fontophilic Avatar answered Sep 22 '22 14:09

fontophilic