Create custom toggle button - That's accessibility friendly
Tags: html, css, javascript, a11y
Published: 2020-08-10 13:11:59

---
canonical_url: https://dipankarmaikap.com/create-custom-toggle-button-accessibility-friendly/
---
In this blog, we are going to create a custom toggle button like the above image. We are also going to make the toggle button accessibility friendly so everyone can have a great experience.

You can find all the code in [my GitHub](https://github.com/dipankarmaikap/custom-toggle-button) and feel free to use it.

##Here is a list of all the steps we are going to take.
1. Design the toggle button
2. Add javascript to make the button work
3. Make the button keyboard accessible

###First Step
```html
<div
   id="toggle-container"
   class="toggle-container"
   role="checkbox"
   aria-checked="false"
   tabindex="0"
   >
   <div id="toggle-button" class="toggle-button">
      <p>
         Turn
<span id="toggle-button-text" class="dynamic-text">On</span>
      </p>
   </div>
   <p id="toggle-container-text">Off</p>
</div>
```
Let’s go through the above HTML code. The first `div` is our toggle button container. It has a few attributes `id`, `class`, `role`, `aria-checked`, and `tabindex`. If you are thinking why all this attributes id and class should be enough to create our toggle button. You would be not completely wrong but the other three attributes are very important to make this toggle button accessibility friendly and its considered best practice.

Next within the first div we have another div and this will act as the button. The two `p` tags has on and off text which we will change based on the toggle state. 

Next, we have to add the CSS to make the toggle button beautiful. 
```css
.toggle-container {
  user-select: none;
  cursor: default;
  background: rgb(173, 173, 173);
  width: 50px;
  height: 100px;
  display: flex;
  text-align: center;
  flex-direction: column;
  padding: 2px;
}
.toggle-button {
  background: white;
  width: 50px;
  height: 50px;
  order: 1;
  font-size: 13px;
  text-align: center;
}
.dynamic-text {
  display: block;
}
.toggle-button.toggle-button-active {
  order: 0;
  color: black;
}
.toggle-container.toggle-container-active {
  background-color: rgb(16, 121, 190);
  color: white;
}
```
The above CSS is almost self-explanatory. This is our button disable or off mode style. The last two lines of CSS are for the active state of our toggle button. We will toggle those two classes based on our button state.
##Second Step
Ok so by now you should have a nice toggle button but it does nothing when you click on it. Now we will make the toggle button work by adding javascript.
```js
var initialState = false;
var toggleContainer = document.getElementById("toggle-container");
var toggleButton = document.getElementById("toggle-button");
var toggleContainerText = document.getElementById("toggle-container-text");
var toggleButtonText = document.getElementById("toggle-button-text");
```
We are selecting our HTML elements by their ID. Also, we have a variable called `initialState` with the value of `false`. Now we can add an event listener to `toggleContainer` and toggle the active classes to make the button work.
```js
toggleContainer.addEventListener("click", handelClick);
function handelClick() {
  initialState = !initialState;
  toggleContainer.classList.toggle("toggle-container-active");
  toggleButton.classList.toggle("toggle-button-active");
  if (initialState) {
    toggleContainerText.innerHTML = "On";
    toggleButtonText.innerHTML = "Off";
    toggleContainer.setAttribute("aria-checked", "true");
  } else {
    toggleContainerText.innerHTML = "Off";
    toggleButtonText.innerHTML = "On";
    toggleContainer.setAttribute("aria-checked", "false");
  }
}
```
Ok, so we added an event listener to `toggleContainer` and passed a function called `handelClick()`. When a user clicks in the `toggleContainer` the `handelClick()` function will run and toggle the two active classes in `toggleContainer` and `toggleButton`.

We also have to track our button current state. By default it’s inactive and that’s why we declared a variable `initialState` above. So now on every click we are changing the value of `initialState` and based on that we are changing the text and `aria-checked` attributes value.

We are almost done. If you check now our button looks great and works almost perfectly. We added `tabindex` to make this button accessible by pressing tab on the keyboard and we are changing the `aria-checked` attribute so voice translator programs can track that. We have one more step left that is making this button work on keypress.

##Making accessibility friendly
Like we have a click event listener in `toggleContainer` we are adding a keydown event listener to `toggleContainer` and passed a `handleKeydown()` function.
```js
toggleContainer.addEventListener("keydown", handleKeydown);
function handleKeydown(event) {
  var flag = false;
  console.log(event);
  switch (event.keyCode) {
    case 32:
      handelClick();
      flag = true;
      break;
    case 13:
      handelClick();
      flag = true;
      break;
    default:
      break;
  }
  if (flag) {
    event.stopPropagation();
    event.preventDefault();
  }
}
```
In `handleKeydown()` function, we have a switch statement that tracks for spacebar and enter key and run our `handelClick()` function.

We also have a variable called flag and its value is by default `false` and if users press either space or enter we are changing its value to `true` and running the last two functions.

Finally, now you have a working toggle button that works on click and if you press spacebar or enter key it works same way. Its fully accessibility friendly and follows best practices.

You can read more in detail about best practices on [w3.org](https://www.w3.org/TR/wai-aria-practices/#checkbox). IF you want to know about key codes for each key visit [keycode.info](http://keycode.info/).

Find the project files [here](https://github.com/dipankarmaikap/custom-toggle-button).

I have tried to keep this as short as possible but if you have any questions please feel free to ask them in the comment. Stay safe and keep your surroundings clean 🙂