jannef jannef - 1 year ago 157
HTML Question

JS: Click event not firing when using keyboard navigation

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.

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download