Build an HTML toggle switch in just 7 lines of code using Vue & TailwindCSS

Jamie Carter
Frontend Weekly

--

Yes you’ve read that right. 6 lines of HTML and 1 line of javascript. 👍

Build a toggle switch using vuejs and tailwind
An example of what we’ll build in this article

The toggle button includes a large clickable area, which includes a title that can be used to explain the option.

Update

This article has been superseded by my latest article — Build a CSS only toggle switch using TailwindCSS — which offers a more flexible component and requires no javascript. Enjoy.

If you are looking an IE friendly version then continue reading but note that this component is not semantically correct HTML.

Tools used

Vue.js

If you haven’t used vue.js before, then I highly recommend it! You can learn more about the javascript framework here.

Although this tutorial uses vue, it should be very simple to convert this design to any framework as it just uses a single variable.

TailwindCSS

Also if you’ve not heard of tailwindcss it’s a utility-first CSS framework and it’s incredibly powerful! In super simple terms you use lot of very specific class names to shape the design of your site, for example ml-0 is 0px left margin and pt-2 is 0.5rem padding top.

I’m a recent a convert to utility-first css. I will admit it took me two, or three, attempts to wrap my head around it. Also I was resistant to learn a new framework especially when I love using SCSS but after committing to give it a real try for a whole project I’m not sure I can go back to SCSS.

One of the more powerful features is how it allows me to make my designs responsive without the need to write a single media query! For example I can do the following:

class=”w-full md:w-1/2"

Which gives a width 100% as a base and width 50% after 768px browser width. How cool!

You can find more info about tailwindcss here.

Let’s code!

Ok, after that quick overview lets dig into some code! 💻

Step 1 - The HTML outline

Our first step is to build the underlying HTML structure of the toggle switch.

We have a toggle title and then the toggle button.

Here it is important to remember that we should always try to make any interfaces we build as easy to use as possible to use.

Following this rule we are going to make it so that the user can click either the toggle switch or the title. I personally find it annoying when I have to click a small toggle, pressing anywhere on the whole block just feels much more natural.

Base HTML structure for our toggle switch

Ok, so as you can see we now have a div that contains a title, our toggle switch, and then a switch (inside the switch container).

We can now start building on this template using tailwindcss.

Container

Our first task is to ensure that our title and switch sit in a line, currently they are one above and the other below. To do this we give the ‘container’ the following classes:

flex justify-between items-center px-8 py-6

flex’ gives us block content on the same line (Here’s a handy flexbox guide).

justify-between’ places all the extra space inside a div in-between the elements in a container. By doing this it means the title should always be right on the left edge of the container and the toggle switch should be on the right.

items-center’ means our content is aligned vertically.

‘px-8 py-6’ gives our content some padding so the content isn’t touching the edges of our container. It’s a personal preference but I prefer to give slightly more padding to the left and right sides that I do the top and bottom.

That’s our container block finished.

Header

I have not made any alterations to the header text. I will leave the styling of this down to your preference.

Switch Container

Ok, now for the important part, let’s start building the switch! 😄

Our first task is to style the ‘switch container’ div. Let’s add the following classes to the ‘switch container’ div:

w-16 h-10 bg-gray-300 rounded-full flex-shrink-0 p-1

w-16 h-10’ gives use the width and height dimensions for the switch container.

bg-gray-300’ gives us a nice grey background.

rounded-full’ gives use a nice capsule shaped container with rounded edges.

flex-shrink-0’ prevents the container width from shrinking in size, this sometimes occurs if the browser width is very small.

p-1’ gives us a small amount of padding around our ‘switch container’ so it doesn’t touch the edge.

Great! We now have the basic shape for our ‘switch container’.

Switch

Next, we need to add the actual switch inside the switch container.

Ok to do this let’s add the following classes to the switch div:

bg-white w-8 h-8 rounded-full shadow-md

This will give us a white div thats rounded.

shadow-md’ is an added extra that will give us a small drop shadow around the bottom of the switch. This is an optional class.

Perfect, the base work is done let’s recap what we have done so far.

Round Up

Here is a round up of how our code should be looking:

Ok, nice work if we look at the what we have so far we should see something resembling the following:

Example of base toggle switch
What you should be seeing. Yours will stretch the length of the browser as we have no max-width.

Functionality

Our base template is in, it’s now time to add some functionality to the toggle switch.

This part is relatively simple, we need to add a ‘v-on:click’ function to our ‘switch container’. [A short hand method for ‘v-on:click’ is ‘@click’].

When we click the ‘switch container’ we change a boolean value from true to false, or false to true.

Using a boolean allows us to both make use of that boolean for the actions the toggle will be controlling as well as allow us to change how the toggle looks.

A simple method to change a boolean regardless of it’s current state is like so:

var toggleActive = true;
toggleActive= !toggleActive;

Combining this with the vue ‘@click’ we get:

@click="toggleActive = !toggleActive"

Ok now let’s add this to our ‘switch container’.

Finally we need to create a reactive variable for the click to affect. To do this we need to add a reactive data property to our vue template. Add the following to your vue <script> block.

Great work!

If you use vue devtools in your browser you should be able to see the reactive data variable change when you click the toggle. 👍

Animation

Hooray, we’ve reached the fun part, adding the animations to the toggle switch! 🎉

Ok, so first things first, how do we to tackle the switch’s horizontal slide animation?

The first thought might be to move the switch using margins, changing the margin left to align the switch to the right Another consideration might be to use CSS positioning and then adjust the left property. Both are valid options but there is a better option, ‘transform: translateX()’.

The reason transform is a better consideration is a complicated topic but ultimately it is less work for the browser to render transitions which makes them smoother and less prone to looking janky during the animation. You can find a detailed article on the topic here.

So now we know how we are going to tackle the slide animation it’s time to create it.

Firstly, we need to add the ‘transform’ class to our ‘switch’. Without the ‘transform’ class our translate classes won’t have any effect.

Missing transform from my animations was a common gotcha’ I stumbled on when I first started using tailwind.

Now we need to add a ‘translate-x-…’ class to the switch to move the switch horizontally to the right.

Let’s add the ‘translate-x-6’ class to the ‘switch’ and see how it looks.

How the toggle switch looks with ‘translate-x-6’ applied.

Perfect! 👏 The switch positioning is perfectly aligned and looking great.

Next, we need to change our switch so that the ‘translate-x-6’ class is only applied when the toggle has been activated. We do this using dynamic class binding.

We can toggle a class based on a boolean property. Using the toggleActive reactive data variable we created earlier we can simply toggle a class dynamically ‘on’ or ‘off’. This is the basic function of our animation.

Let’s look at what that looks like:

:class="{ 'translate-x-6': toggleActive,}"

This will add the class ‘translate-x-6’ to our switch when toggleActive is true, and remove it when it is false.

Ok, let’s add this to the switch:

Congratulations 🎉 you have a functioning toggle switch!

But, hang on a minute, it’s not very elegant…

Ok, so the toggle switch is now working but the toggle currently jumps from left to right instantly. Let’s give it some finesse. Firstly let’s add a transition-duration and a transition-timing-function class.

To the class of the ‘switch’ add the following classes:

duration-300 ease-in-out

duration-300’ sets an animation duration time of 300ms, so it will take 300ms for the ‘switch’ to move from left to right.

ease-in-out’ changes the animation so that the start and the end movements are much slower than the movement during the middle of the animation, making it feel more natural. There is a great explanation of how this alters the animation here.

Our ‘switch’ code now looks like so:

Ok let’s see how that has change our switch animation:

A lovely smooth slide animation 👍

We are so close now, just one last addition. Let’s change the background colour of the ‘switch container’ when the switch is active. This will be better for user experience as we will be able to see which toggles are activated at a glance.

Following the same principle we used for the translate class we will add a background colour class to the ‘switch container’:

:class="{ 'bg-green-400': toggleActive}"

Don’t forget to add the transition classes as well:

duration-300 ease-in-out

Let’s take a look at the code for the ‘switch container’:

🎉 We have a complete working toggle switch with a nice design and some smooth animations, great work!

Build a toggle switch using vuejs and tailwind
We made it!

User experience

As a departing thought, we should always consider what ways we can improve the user experience for the toggle switch. One example, rather than forcing a user to click the small toggle switch we should rather allow the user to click anywhere along the block to trigger the toggle.

To do this we just need to move the ‘@click’ function on the ‘switch container’ to the main ‘container’.

TLDR;

Below is the code for a nice little HTML toggle switch built with vue and tailwindcss. This template could easily be converted to react or angular or any other js framework.

Key points:

  • Use translate for movement over position / margin
  • Don’t forget to add the ‘transform’ class when using transforms for animations

Complete Toggle Switch Code

Let me know if you have any UI components you are struggling to build in javascript and CSS / TailwindCSS because you never know it might just be my next article 😉.

Find me on twitter 👉 @jamiecarter7

--

--

Jamie Carter
Frontend Weekly

Product designer, frontend developer and pharmacist. Passionate about Design, UX, CSS (Tailwind), DataVis and AstroJS. Twitter: @jamiecarter7. Work: simple.org