Trap ARROW KEY navigation on modal using Screen Readers

546 Views Asked by At

I'm dealing with an issue trying to trap the navigation inside a modal using TAB/ARROW keys.

Was using a function like this to avoid the keys action to being triggered:

        component.addEventListener("keydown", function (e) {
          if((e.key === 'Tab' && !(e.shiftKey && e.key === 'Tab')) || e.key === 'ArrowDown' || e.key === 'ArrowUp'){
            e.preventDefault();        
          }
        });

The problem is when using the arrow keys with some screen reader like NVDA or JAWS. The arrow button doens't trigger anything on the browser, it seems like it's some action on the screen reader like a shortcut.

Basically that function works, but when using screen reader I get this weird behavior. Could you some hand on that.

Trap the navigation even when using screen readers or get some explanation why it's not working.

1

There are 1 best solutions below

0
QuentinC On

This isn't a weird behavior, what you observe is perfectly normal.

I won't repeat here the whole thing since it would be quite long, but to make it as short as I can, there are two ways to see web contents with a screen reader:

  • Whether you consider your web page as being a text document, like in Word. In screen reader terminology, this is called the browse mode (NVDA) or virtual cursor mode (Jaws).
  • Or you consider it as an application, like a native GUI program. This is called input mode, form mode, focus mode or application mode.

When you are in browse mode, you use your keyboard to control a cursor, which works basically like in Word. Arrow keys allow to move between characters, words, and lines. A lot of other shortcuts allow to jump directly to headings, buttons, form elements, and other elements.

What is important to keep in mind is that in browse mode, all these shortcuts and in particular including arrow keys are never transmitted to your page. They perform only their reading and moving functions.

When you are in application / focus / form mode, you use tab to move between focusable elements, and there all key press are transmitted to your page, almost as if there was no screen reader at all. However, it's impossible to precisely review ordinary text in this mode.

Both modes are important, and the screen reader user can decide to switch betwen one and the other at any moment, depending on what he/she wants to do. Shortcut to switch with NVDA is Insert+Space, for example. Screen readers also switch automatically on various occasions, trying to guess what the user is going to do next.

What is important to realize is that, if you want to capture arrow keys for your own use, the screen reader has to be in form mode.

The first of all is to make your element focusable with tabindex=0 if it isn't already focusable. For the rest, test, test, test with real screen reader users to see if they well understand how it works or not, and how screen readers behave (ideally, test several screen readers on several platforms).

Be very careful, though: scren readers switch to form mode automatically in several situations, and depending on what you do in response to pressing arrow keys, you may prevent less experienced screen reader users from getting out of your component easily. You need to make sure that, whether you are only performing quite common navigation, or that the user knows that he/she's in a particular situation where arrow keys work differently than normal (for example in a game)