Skip to content
Advertisement

How to make a div element navigable by arrow keys when using JAWS

I would like to make a div element navigable by arrow keys when JAWS is running. The div should not be navigable using the TAB key; so using tabindex is not applicable.

Here is an example snippet of the html/reactjs structure.

const label1 = 'First label';
const label2 = 'Second label';
const prefix = 'Prefix';
const suffix = 'Suffix';

const screenReaderText = `${prefix} ${label1} ${suffix} ${label2}`;

return (
  <>
    <h1>Heading</h1>
    <div className="container" aria-label={screenReaderText}>
      <div aria-hidden="true">{label1}</div>
      <div aria-hidden="true">{label2}</div>
    </div>
    <footer>Footer</footer>
  </>
);

The two nested div should not be available to the accessibility API; hence the use of aria-hidden="true". The div with className="container" should be navigable by arrow keys when using JAWS. Moreover, when navigating to the container div, JAWS should read out a label which is a combined and modified text of the contents the two inner div.

The navigation flow should be: h1 -> container div -> footer

I am guessing I should apply an appropriate role to the container div. The tree role gives the desired effect, but reading about it suggests that it is not best practice for this use case.

Advertisement

Answer

To avoid confusion about “navigating” the element: You want a screen reader to read the text in browse mode like regular text, which JAWS already does by means of the arrow keys, line by line.

Also, the whole text Prefix Label1 Suffix Label2 should be in a single line, even though it’s visually presented in separate lines.

If you want text to be exposed only to assistive technology like screen readers, the famous visually-hidden CSS class comes into play (fka sr-only).

There’s a great explanation on how it works by Scott O’Hara: Inclusively Hidden

/* ie9+ */

.visually-hidden:not(:focus):not(:active) {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}
<h1>Heading</h1>
<div className="container">
  <div class="visually-hidden">Prefix Label1 Suffix Label2</div>
  <div aria-hidden="true">Label1</div>
  <div aria-hidden="true">Label2</div>
</div>
<footer>Footer</footer>

Why not aria-label?

The accessible name of an element, provided by means of aria-label or aria-labelledby is not announced in browse mode (when reading).

It is only used to build the lists of, f.e. headlines or landmarks, and in form mode, when navigating with Tab.

By default, the accessible name is built from the text contents, so using visually-hidden is taken into account, should you add a role or interaction.

Mismatch between visual and accessible text

Since the text in your question is probably not the one used in production, I’d like to point out that it’s important to not divert too much between visual text and text accessible to assistive technology.

A lot of screen reader users are sighted, and rely on the two matching.

For example, visually presenting the two labels in two separate lines creates the expectation for JAWS users that they’d need to use arrow down twice, not once.

Also, how are sighted users making sense of the two labels without a screen reader, if prefix and suffix are missing?

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement