Getting keyboard-focusable elements
Tags: javascript
Published: 2020-02-05 05:47:37

---
title: Getting keyboard-focusable elements
description: How to get all keyboard-focusable elements
canonical_url: https://zellwk.com/blog/keyboard-focusable-elements
cover_image: https://zellwk.com/images/2020/get-focusables/modal.png
tags: javascript
published: true
---

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

<figure role="figure">
  <img src="https://zellwk.com/images/2020/get-focusables/modal.png" alt="Modal with two inputs and one button.">
</figure>

I can get the focusable elements with `querySelectorAll`.

```js
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:

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

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

```js
/**
 * 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][1]. 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!

[1]: https://github.com/zellwk/useful-js-snippets "Useful JavaScript snpiiets"

<hr>

Thanks for reading. This article was originally posted on [my blog](https://zellwk.com/blog/keyboard-focusable-elements). Sign up for my newsletter if you want more articles to help you become a better frontend developer.