DEV Community

Cover image for Snippet: Making your buttons fully accessible
Tammy Shipps
Tammy Shipps

Posted on

Snippet: Making your buttons fully accessible

I'd always been under the (mistaken) impression that buttons, in order to be accessible, needed to listen to click events and the enter key - but my bubble was unexpectedly burst by reading the specs.

In order to be truly accessible, buttons should activate on both the enter key, and the space bar. So, if you're like me and you're a) lazy and b) lazy, you can accomplish this pretty easily with a snippet like this one:

// Enable space and enter activation on buttons
$("button, a.button, a.btn").on("click tap keydown", function(event) {
  if (event.type === 'click'){
    return true;
  } else if (event.type === 'keydown') {
    let code = event.charCode || event.keyCode;
    if ((code === 32)|| (code === 13)){
      $(event.target).get(0).click();
    }
  } else {
    return false;
  };
});

Let's break down what this does.

$("button, a.button, a.btn")

Select elements that are buttons, or that act like buttons:

.on("click tap keydown", function(event) {

Here we put the events we wish to capture, and then grab the event object. It's important to include 'click' here, even though we really want key presses, because:

if (event.type === 'click'){
  return true;
} ...

We want to allow interaction events to work as normal if they are clicks, so let's catch them.

} else if (event.type === 'keydown') {
  let code = event.charCode || event.keyCode;
  if ((code === 32)|| (code === 13)){
    $(event.target).get(0).click();
  }
} else {
  return false;
};

Okay, now we get to the key presses, and the magic! First, let's make sure we're dealing with a keypress. If we are, then we need to see which key was pressed, since we only care about 2 keys. Depending on the event, we might get a code different ways, so we'll check event.charCode and event.keyCode.

If the code returned is 32 then the user pressed the space bar, and code 13 corresponds to the enter key.

$(event.target).get(0).click();

This is the magic right here - this will find exact the button that was interacted with and fire off a good old-fashioned click event, making the button activate.

Remember when I said that we need to include click as a captured event? That's because we might be dealing with a fake button (such as an anchor tag with role="button"), and by being explicit, we're making sure not to introduce bugs unintentionally, and clicks remain working as normal.

That's my method! Do you have your own? Let me know!


Edit: Thanks to Andrew Nevins for reminding me that keypress is depreciated!

Discussion (2)

Collapse
anevins12 profile image
Andrew Nevins

Thanks for writing this. I was wondering if you should be using keyup instead so that the event does not trigger on a down event and I think keypress is deprecated.

Guidance on not triggering down-events from sc. 2.5.2 Pointer Cancellation: w3.org/TR/WCAG21/#pointer-cancella...

Guidance on keypress event from MDN: developer.mozilla.org/en-US/docs/W...

Collapse
mizziness profile image
Tammy Shipps Author

Oh right, I'd forgotten about that! Thank you! I checked the Mozilla docs and they suggest keydown, so I'll give that a shot. Editing my code accordingly. <3