It’s toggle day! Let’s create a toggle that animates when you click it only with Tailwind CSS. Zero JavaScript required!
A toggle is a button that can be toggled on or off. It’s a common UI element that is used in many applications. For example, a toggle button can be used to turn on or off a light or a feature in an application. ( Like the one we have in the demo ).
First, let’s create the wrapper for the toggle. We’ll use the label
element to wrap the toggle and the input
element to toggle the state of the toggle. The input
element is hidden by default and will be shown when the user clicks on the toggle. We’ll use the for
attribute to associate the input
element with the id
of the toggle. Finally, we’ll use the aria-labelledby
attribute to associate the label with the toggle. This will make the label accessible to screen readers.
for="theme-toggle"
: Associates the input
element with the id
of the toggle.We’ll use the sr-only
class to hide the text from the screen and only show it to screen readers.
<span class="sr-only">Toggle theme</span>
We’ll use a sun and a moon SVG to represent the toggle state. So let’s position them on the left and right side of the toggle.
Light mode SVG
absolute
: Positions the SVG absolutely.left-[0.5em]
: Positions the SVG on the left side of the toggle.top-1/2
: Positions the SVG in the middle of the toggle.flex
: Makes the SVG a flex container.size-8
: Sets the size of the SVG.-translate-y-1/2
: Moves the SVG up by half its height.items-center
: Centers the SVG vertically.justify-center
: Centers the SVG horizontally.aria-hidden="true"
: Hides the SVG from screen readers.<svg class="absolute left-[0.5em] top-1/2 size-8 -translate-y-1/2 items-center justify-center " aria-hidden="true"></svg>
Dark mode SVG
absolute
: Positions the SVG absolutely.right-[0.5em]
: Positions the SVG on the right side of the toggle.top-1/2
: Positions the SVG in the middle of the toggle.size-8
: Sets the size of the SVG.-translate-y-1/2
: Moves the SVG up by half its height.<svg class="absolute right-[0.5em] top-1/2 size-8 -translate-y-1/2 items-center justify-center" aria-hidden="true"></svg>
We’ll use the input
element to toggle the state of the toggle. The input
element is hidden by default and will be shown when the user clicks on the toggle. We’ll use the for
attribute to associate the input
element with the id
of the toggle.
peer
: Makes the input element a peer element.sr-only
: Hides the input element from the screen.id="theme-toggle"
: Associates the input
element with the id
of the toggle.name="theme-toggle"
: Associates the input
element with the name
of the toggle.type="checkbox"
: Specifies that the input
element is a checkbox.aria-labelledby="theme-toggle-label"
: Associates the input
element with the id
of the label.<input
class="peer sr-only"
id="theme-toggle"
name="theme-toggle"
type="checkbox"
aria-labelledby="theme-toggle-label"
/>
We’ll use the span
element to create the slider. We’ll use the id
of the slider to associate it with the id
of the toggle.
absolute
: Positions the slider absolutely.left-[0.25em]
: Positions the slider on the left side of the toggle.top-1/2
: Positions the slider in the middle of the toggle.flex
: Makes the slider a flex container.size-10
: Sets the size of the slider.-translate-y-1/2
: Moves the slider up by half its height.items-center
: Centers the slider vertically.justify-center
: Centers the slider horizontally.rounded-full
: Rounds the slider.transition-all
: Transitions the background color of the slider.duration-300
: Sets the duration of the transition to 300 milliseconds.peer-checked:left-[calc(100%-2.75em)]
: Moves the slider to the right when the toggle is checked.peer-focus:ring-2
: Adds a focus ring to the slider when the toggle is focused.peer-focus:ring-blue-400
: Sets the focus ring color to blue.<span
id="theme-toggle-label"
class="absolute left-[0.25em] top-1/2 flex size-10 -translate-y-1/2 items-center justify-center rounded-full bg-orange-600 to-zinc-400 transition-all duration-300 peer-checked:left-[calc(100%-2.75em)] peer-focus:ring-2 peer-focus:ring-blue-400"
aria-hidden="true">
</span>
<label
for="theme-toggle"
class="flex items-center cursor-pointer relative h-12 w-24 rounded-full bg-zinc-100 ring-1 ring-inset ring-white shadow mx-auto"
>
<span class="sr-only">Toggle theme</span>
<!--- Light mode SVG -->
<svg
class="absolute left-[0.5em] top-1/2 flex size-8 -translate-y-1/2 items-center justify-center text-orange-600"
aria-hidden="true"
>
</svg>
<!--- Dark mode SVG -->
<svg
class="absolute right-[0.5em] top-1/2 size-8 -translate-y-1/2 rounded-full text-orange-600"
aria-hidden="true"
>
</svg>
<input
class="peer sr-only"
id="theme-toggle"
name="theme-toggle"
type="checkbox"
aria-labelledby="theme-toggle-label"
/>
<span
id="theme-toggle-label"
class="absolute left-[0.25em] top-1/2 flex size-10 -translate-y-1/2 items-center justify-center rounded-full bg-orange-600 to-zinc-400 transition-all duration-300 peer-checked:left-[calc(100%-2.75em)] peer-focus:ring-2 peer-focus:ring-blue-400"
aria-hidden="true"
></span>
</label>
That’s it! You now know how to create an animated toggle with Tailwind CSS. You can use this code as a starting point for your own toggle. Make sure to make it accessible to screen readers.
Have a great day!
/Michael Andreuzza
"I bought a beautiful theme from Lexington a couple weeks ago. I didn't know Astro at the time, but Michael helped me get set up and really went above and beyond with his support. Now I'm happily redoing my site to look gorgeous with his template."
Stuart
Creator of saasydb.com
"Michael is one of the best designers on Twitter, would highly recommend his Lexington Themes if you want something in tailwind that doesn’t look the same as everyone else!"
Alex Hughes
letsloopin.com
Get lifetime access to every theme available today for $199 and own
them forever. Plus, new themes, lifetime updates, use on unlimited
projects and enjoy lifetime support.
No subscription required!
Beautifully designed HTML, Astro.js and Tailwind themes! Save months of time and build your startup landing page in minutes.