Getting keyboard-focusable elements

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…

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>.

Modal with two inputs and one 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:

  1. <a>
  2. <button>
  3. <input>
  4. <textarea>
  5. <select>
  6. <details>
  7. Elements with tabindex set to 0
  8. 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'))
}

Print Share Comment Cite Upload Translate
APA
Zell Liew | Sciencx (2024-04-18T15:59:50+00:00) » Getting keyboard-focusable elements. Retrieved from https://www.scien.cx/2020/01/29/getting-keyboard-focusable-elements/.
MLA
" » Getting keyboard-focusable elements." Zell Liew | Sciencx - Wednesday January 29, 2020, https://www.scien.cx/2020/01/29/getting-keyboard-focusable-elements/
HARVARD
Zell Liew | Sciencx Wednesday January 29, 2020 » Getting keyboard-focusable elements., viewed 2024-04-18T15:59:50+00:00,<https://www.scien.cx/2020/01/29/getting-keyboard-focusable-elements/>
VANCOUVER
Zell Liew | Sciencx - » Getting keyboard-focusable elements. [Internet]. [Accessed 2024-04-18T15:59:50+00:00]. Available from: https://www.scien.cx/2020/01/29/getting-keyboard-focusable-elements/
CHICAGO
" » Getting keyboard-focusable elements." Zell Liew | Sciencx - Accessed 2024-04-18T15:59:50+00:00. https://www.scien.cx/2020/01/29/getting-keyboard-focusable-elements/
IEEE
" » Getting keyboard-focusable elements." Zell Liew | Sciencx [Online]. Available: https://www.scien.cx/2020/01/29/getting-keyboard-focusable-elements/. [Accessed: 2024-04-18T15:59:50+00:00]
rf:citation
» Getting keyboard-focusable elements | Zell Liew | Sciencx | https://www.scien.cx/2020/01/29/getting-keyboard-focusable-elements/ | 2024-04-18T15:59:50+00:00
https://github.com/addpipe/simple-recorderjs-demo