If you create JavaScript widgets, one of the key parts to accessibility is managing focus.
To manage focus, you need to find keyboard-focusable elements.
When you know the contents
It's easy to find keyboard-focusable elements if you know the contents of the element beforehand.
For example, I know the focusable elements in this modal are <input>
and <button>
.
I can get the focusable elements with querySelectorAll
.
const focusableElements = [...modal.querySelectorAll("input, button")];
When you don't know the contents
It's harder to find keyboard-focusable elements if you don't know the content beforehand.
After some research, I realised you could only focus on these elements with a keyboard:
<a>
<button>
<input>
<textarea>
<select>
<details>
- Elements with
tabindex
set to0
- Elements with
tabindex
set to a positive number
We can get all keyboard-focusable elements with the following querySelectorAll
. It looks a little complicated, but there's no other way to include everything:
const keyboardfocusableElements = document.querySelectorAll(
'a, button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])'
);
Some elements (like button
) can be disabled. Disabled elements are not focusable. We can remove these elements with filter
.
const keyboardfocusableElements = [
...document.querySelectorAll(
'a, button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])'
)
].filter(el => !el.hasAttribute("disabled"));
Turning it into a function
This querySelectorAll
code is hard to read. We can put the entire thing into a function to make it more understandable.
/**
- Gets keyboard-focusable elements within a specified element
- @param {HTMLElement} [element=document] element
- @returns {Array}
*/
function getKeyboardFocusableElements(element = document) {
return [
...element.querySelectorAll(
'a, button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])'
)
].filter(el => !el.hasAttribute("disabled"));
}
Useful JavaScript functions
I started keeping snippets of JavaScript functions I find useful in a Git repository. It's tiny now though. I'll add more to it as I go along.
Hope you find it useful.
If you have any suggestions to add to this repo, please let me know!
Thanks for reading. This article was originally posted on my blog. Sign up for my newsletter if you want more articles to help you become a better frontend developer.