Create custom toggle button – That’s accessibility friendly

custom toggle button
Custom toggle button

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

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

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

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.

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.

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. IF you want to know about key codes for each key visit keycode.info

Find the project files here.

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 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *