Building Toggle Switches for the Web - Using Buttons vs Checkbox Inputs

Photo by Arthur Mazi on Unsplash

Building Toggle Switches for the Web - Using Buttons vs Checkbox Inputs

How to decide what to use

Toggle switches are a common feature we see particularly in mobile application interfaces. They are UI controls that have two states - on and off - like a light switch. You might argue that its name lends itself to the behaviour of a literal light switch.

Recently, a team member was working on something that leverages this UI control. Without thinking too deeply about it, if I were to work on something similar my first thought would be to use a checkbox. A checkbox typically supports two states - checked and unchecked. It serves as a binary input. A toggle switch is functionally very similar, with an on and off state. Now, there is no 'switch' element in HTML. So we could totally use a checkbox for its base implementation, right? Possibly.

However, in this instance, a button was used. Okay. So that was interesting and natural my curiosity was piqued. I sought out the reason why and my team lead explained it. It had to do with web accessibility guidelines. When choosing the base element to use for implementing a switch, you have to consider the context in which the switch is being used.

This raises the question: in what contexts is a checkbox suitable for implementing this functionality and when should you use a button instead?

When to use the <button> element

I am going to quote from a source that puts it quite succinctly.

If the toggle causes an immediate action (such as switching a theme) and therefore relies on JavaScript, it should use a <button>... - Kitty Giraudel on building An accessible toggle.

In that statement, she gives us an example of when we should use a button - the popular theme switchers we see on the web. The Hashnode Dark mode switch in the blog editor view is a perfect example as we can see below.

A gif of Hashnode's dark mode switch

Clicking it causes an immediate action. In this case, my screen went from dark mode to light mode when I 'turned the dark mode option off'.

In fact, if you take a closer look, you'll other examples similar to the Dark mode switch. Hashnode provides the ability to turn on or turn off article editing in markdown. In my case, it is turned on. There is also the option to turn on / off Grammarly spellcheck while editing. All these functions require the need to trigger an immediate, instantaneous action that may or may not be visible. To do that, we need JavaScript so in this case using a button would be the right approach to take.

Here's a fun activity. If you have a Hashnode blog, try inspecting those actions to see what base element is used to implement them.

Here are some other examples similar to the dark mode switch as seen above.

Theme Switcher demo from CSS Tricks

Source: Article on CSS Tricks by Maks Akymenko

Theme Switcher from a LevelUp article demo

Source: LevelUp article demo by FAM

Another scenario off the top of my head where using a <button> element is appropriate is when you're providing your users with the ability to opt-in to using a new version of your app. Can you think of any other examples?

Now that we know when to use a button, let's talk about some of the other use cases where a checkbox can be used to implement a visual toggle switch.

When to use the <input /> element with type="checkbox" .

Are you up for some cookies? It is not the mouth-watering, scrumptious, decadent kind though. It's the kind that tracks your activity on a website. A lot of sites just present you with the notice and force you to accept them without providing you with opt-in options. Not very nice.

Source: Designpress.com

Some are more gracious about it. A popular one among developers is StackOverflow. Picture the scenario: You asked Google a dev question. One of the search results you're given is from StackOverflow. Let's assume this is a new laptop. You're just using the browser for the first time today. You click on the link, the web page loads and you're presented with answers. But wait, there's a massive overlay on the left side of the screen.

You're being provided with an opportunity to decide what cookies you want on your computer. They are super nice and gracious about it though. If you're anything like me recently and choose to Customize settings, you're presented with a screen that looks similar to this image below:

The list of cookies is displayed with an option to turn each one of them on or off. There is no immediate effect when these toggles are clicked individually. You have to click Confirm your choices to finalize the process of choosing your privacy preferences and actually turn off those cookie settings. In this case, Confirm your choices is like a submit button and the cookie preferences are like form questions.

This scenario is one where using an <input> element with type="checkbox" is appropriate. An input element can be styled as a toggle switch in a situation where you want the user to provide all user preferences to be used in subsequent interactions without triggering an immediate change.

It's time for another little fun activity. Take a moment to inspect the cookie preferences modal for StackOverflow. What do you see?

As with most things in web development, there are no complete absolutes. The next section addresses that for this topic.

Button-style toggle switches that do not trigger immediate actions.

Canva is another example of a website that uses toggle switches to provide users with the option to set their preferences regarding the cookies they want to be activated or not.

A screen of the cookie preferences modal on Canva

However, in their case, they use buttons for their implementation as you can see in the image below.

A screen of the cookie preferences modal on Canva with inspect mode open. The switch for Functional cookies element is highlighted in the Element tab in the dev inspector.

I think it suffices to say that buttons can be used in contexts where you can also use a checkbox but the reverse is not the case. I'll let you mull over that as I wrap this up.

Conclusion

When presented with the task of building a toggle switch component, the decision on whether to use a checkbox or a button boils down to the effect the component should have on the application when clicked. If you need to apply an instant change to the application when the switch is clicked, use a button. If a click does not trigger an instant change, it might be worth deciding on a case-by-case basis.

Regardless of the context where either of these two elements is used, remember to always set the role of the element to switch and set up the appropriate aria-* properties correctly. The goal should ultimately be to build truly accessible toggle switches.

References and additional reading