JS: Click event not firing when using keyboard navigation

Viewed 4890

WCAG 2.0 AA compliance requires, among other things, full support for keyboard only navigation of a web site. I am utilizing tabindex and role attributes to provide tab-key navigation to user. While implementing the accessibility features I came across following problem:

https://jsfiddle.net/fn9wvp1s/1/

<div id="app">
  <div>
    <button tabindex="1"
            onclick="console.log('clicked')">
      button
    </button>
    <div tabindex="2"
         onclick="console.log('clicked')"
         class="div-button"
         role="button">
      selectable div
    </div>
  </div>
</div>

Clicking the elements with a mouse naturally works, and click event is fired as expected. However, when using tab to navigate to the elements and hitting return/space, the event is only fired for the button. Why is this? Can I enable the click event from keyboard to the div element somehow?

I am quite aware of various workarounds, including binding key press event to the div. Ended up refactoring the markup and replacing the divs with buttons, but would still like to know why the thing is implemented this way.

2 Answers

According to the MDN:

On its own, role="button" can make any element (e.g. <p>, <span> or <div>) appear as a button control to a screen reader

following warning specifically describes, that the attribute does not provide any built-in keyboard functionality:

Warning: Be careful when marking up links with the button role. Buttons are expected to be triggered using the Space or Enter key, while links are expected to be triggered using the Enter key. In other words, when links are used to behave like buttons, adding role="button" alone is not sufficient. It will also be necessary to add a key event handler that listens for the Space key in order to be consistent with native buttons.

In other words - where example provided describes <a> tag behavior - role='button' does not have this funcitonality:

document.querySelectorAll('[role="button"]').forEach(function(button) {
    button.addEventListener('keydown', function(evt) { 
       if(evt.keyCode == 13 || evt.keyCode == 32) {
           button.click();
       }
    });  
});

As it'd exceed mentioned attribute's functionality, which is for screen readers purpose only.

I am working on an accessible jquery datepicker and we use NVDA as screen reader. The above mentioned solution is not working in edge browser. In jquery datepicker all dates are reside inside anchor tag. By using the keyboard arrow, we navigate through the date picker. But in edge browser screen reader prevent keypress event so we cant navigate.

Only user need to manually switch to focus mode then only the keypress event will trigger.

Related