Brief Note on Buttons, Enter, and Space

Keyboard interaction note for just one control from the entire panoply of HTML controls:

There are scenarios where you want a user to be able to hold the button down, just submitting to oblivion. There are also scenarios where the user may want to be able to dismiss, perhaps if they are confirming a thing is interactive owing to poor visual design affordances and don’t want to commit.

These can blow up once a screen reader is in play. If you run Narrator/Edge, pressing Space is the same as pressing Enter, but holding either down does not repeatedly fire the event. NVDA/Firefox and JAWS/Chrome treat Space as Enter — fires on key down and holding it down continues to fire. The Windows screen readers all intercept the event, so you cannot listen for which key was pressed in your page. VoiceOver/Safari/macOS behaves as if VO was not running, and (in my script) the keyboard events are captured.

Example

I made an example you can break.

The following button will increment a counter for each time either the Enter or Space triggers it. Try it with these interactions:

  1. Hold down Enter and compare the Total count and Enter count.
  2. Hold down Space and then (while holding down Space) pressing Tab. Compare the Total count and Space count.
  3. Fire up a screen reader and repeat steps 1 and 2.
Activation test

0

0

0

Takeaway

I regularly encounter developers who are unfamiliar with the nuance of native control keyboard interactions. When they role-up a <div> and try to re-create native interactions, they often introduce a mis-match, potentially messing up expectations from skilled users. Especially when native and custom controls are mixed on a page, application, site, etc.

As an aside, divergence from native controls can can be apparent in Windows High Contrast Mode / Contrast Themes. In most cases it won’t be an issue (if you specify a border), but if you mix native and custom controls on a page the color differences could be confusing.

This post does not advocate for any particular approach other than being consistent and probably managing expectations. And testing. Please, for the love of the pantheon, test.

8 Comments

Reply

Using VoiceOver with Safari on a Mac, if you use the VoiceOver buttons (in my case Ctrl + Alt) together with the space bar, the total count goes up, but the space and enter counts don’t.
Do you know why that is?

Verena; . Permalink
In response to Verena. Reply

My script listens for keypresses. The screen reader intercepts keypress and then passes its own event to the button to trigger it.

A lot of scripts on the web work this way, which is why listening for specific keyboard actions tends to fall down when a user comes in with a screen reader.

As a comparison, if I am running JAWS and press Enter, the total count increments but not the Enter count. If I press Alt + Enter, then the Enter count also increments because it is being passed through directly to the button. The same is true if I press JAWS Key + 3 (which activates the JAWS pass-through), and then press Enter — the Enter count increments.

Reply

Interesting indeed, so, now that you know the issue at hand, what do you think may be the best approach to let the user know about these issues? I mean, in the end if I’m not able to have a solution to fix them all, then I better keep the user in the loop of some unexpected behaviors (right?).

Since I’m quite new to a11y, I can’t really think of a good semantic-html approach that helps the user in that regard. But, on the other hand, given that people using readers tend to be experienced one, maybe they are already aware of this kind of “unexpected behaviors”, so, there’s no actual need of letting them know about what their readers do (right?). What do you think?

well1791; . Permalink
In response to well1791. Reply

Your comment implies you are considering the screen reader use case, so I am answering as if that is the case.

Interesting indeed, so, now that you know the issue at hand, what do you think may be the best approach to let the user know about these issues?

The issue (or issues) only exists if developers use non-native interactive controls and/or rely on JavaScript to capture keyboard events. In other words, there is no issue unless the developer creates one.

I mean, in the end if I’m not able to have a solution to fix them all, then I better keep the user in the loop of some unexpected behaviors (right?).

The solution is to not rely on non-native controls and/or not rely on script to capture keyboard events. The only way you could notify the user of unexpected behaviors is to test across all screen reader and browser combinations, potentially across versions, along with all interaction types.

Since I’m quite new to a11y, I can’t really think of a good semantic-html approach that helps the user in that regard.

Do not rely on non-native controls and/or do not rely on script to capture keyboard events.

But, on the other hand, given that people using readers tend to be experienced one…

This is very risky assumption. Screen reader users tend to be as comfortable with screen readers (and computers) as the general public overall. A mix of highly skilled and not, distracted and focused, frustrated and chill, comfortable with technology and not, using top hardware and old kit.

What do you think?

I think using native HTML controls and avoiding listening for specific keyboard events is a safe starting point. For example, remember that onclick on a <button> gets you the keyboard support for free.

Reply

I’m currently running up against this issue. I have an element where if you focus on it, and press the down arrow key, magic happens (in all browsers). Turn on VO with Safari, also works. But as soon as you turn on NVDA or JAWS it stops working.

In response to Dean. Reply

That’s not too surprising since screen readers intercept key presses. I suspect when you press the down arrow key while running a JAWS/NVDA that the virtual cursor moves and you hear the next exposed / text node in the DOM.

Reply

It’s good to know how screen readers handle these keys differently. I’ve seen issues before when trying to recreate native button behavior with custom elements. Does the example cover most cases, or are there more we should test?

Stefan Smiljkovic; . Permalink
In response to Stefan Smiljkovic. Reply

Yes, there are more you should test. Every native element that has been re-created with ARIA and every native element when paired with any kind of AT. For example, I wrote a Brief Note on Dismissing Selects and Listboxen which covers just one type of interaction with select menus (and links to some other stuff).

Leave a Comment or Response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>