Create custom toggle button with TailwindCSS
Toggle buttons are common elements of user interfaces. A toggle button is effectively a checkbox input with a dedicated style to better refer to the function.
HTML does not include such a component by default, and you can not change the design of the existing checkbox input. Therefore, many people solve the problem using CSS and JavaScript. However, it is not necessary to use JavaScript either. Even the complex CSS rules and classes can be written purely with TailwindCSS classes.
Let's get started.
The concept
The basic concept is as follows. You should know that the native functionality for checkboxes is that clicking on either the input element or the associated label element changes the input value.
Skeleton
By exploiting this, you can make the input element itself invisible and only use the associated label element.
The basic code looks like this:
<label class="relative inline-block">
<input type="checkbox" class="invisible" />
</label>
In the browser, however, it is still invisible.
I do not use background color on the main container. Later we will add a span tag inside the label element to create the required background color. Why? Because in TailwindCSS you can access the state of the sibling element with the peer
class. So in our case, we can change the design depending on the state of the checkbox element. With this solution, we can change the background color depending on the checkbox state.
With the background and with the peer
class, the code looks like this:
<label class="relative inline-block">
<input type="checkbox" class="peer invisible" />
<span class="absolute top-0 left-0 w-16 h-6 cursor-pointer rounded-full bg-slate-200 border border-slate-300"></span>
</label>
Adding the marker
We then add the small circular status indicator, which is resolved with a span tag. Here we use absolute
position and z-10
as z-index.
<label class="relative inline-block">
<input type="checkbox" class="peer invisible" />
<span class="absolute top-0 left-0 w-16 h-6 cursor-pointer rounded-full bg-slate-200 border border-slate-300"></span>
<span class="absolute top-1 left-1 w-4 h-4 bg-white rounded-full z-10"></span>
</label>
Handling the interaction
Now change the background color and the position of the marker depending on the state of the checkbox. This is what the peer-checked
class is for. If checked, we change the background color and change the position of the checkbox.
<label class="relative inline-block">
<input type="checkbox" class="peer invisible" />
<span class="absolute top-0 left-0 w-16 h-6 cursor-pointer rounded-full bg-slate-200 border border-slate-300 peer-checked:bg-sky-700"></span>
<span class="absolute top-1 left-1 w-4 h-4 bg-white rounded-full z-10 peer-checked:translate-x-10"></span>
</label>
Final adjustments
To make it even nicer, we can add some animation. We are done!
<label class="relative inline-block">
<input type="checkbox" class="peer invisible" />
<span class="absolute top-0 left-0 w-16 h-6 cursor-pointer rounded-full bg-slate-200 border border-slate-300 transition-all duration-1000 peer-checked:bg-sky-700"></span>
<span class="absolute top-1 left-1 w-4 h-4 bg-white rounded-full z-10 transition-all duration-1000 peer-checked:translate-x-10"></span>
</label>