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!
Top comments (2)
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...
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