DEV Community 👩‍💻👨‍💻

DEV Community 👩‍💻👨‍💻 is a community of 967,611 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Ilia Mikhailov
Ilia Mikhailov

Posted on • Updated on • Originally published at

Accessible switch toggle button with svelte.js and tailwind.css

Sometimes, when working with forms, you might want to style your checkboxes to something more fancy than browser defaults. In this article you will learn how to create a switch button in Svelte with the help of tailwind.css.

Toggle Switch

For this example we will use my Svelte template which has Tailwind baked into it.

$ npx degit iljoo/svelte-tailwind-parcel-starter svelte-switch

Enter fullscreen mode Exit fullscreen mode

The hardest part of this is to get the CSS right. Fortunately Tailwind makes it very easy. Start of by creating a Switch.svelte file.

<!-- Switch.svelte -->

  .switch {
    @apply relative inline-block align-middle cursor-pointer select-none bg-transparent;

  .track {
    @apply w-12 h-6 bg-gray-600 rounded-full shadow-inner;

  .thumb {
    @apply transition-all duration-300 ease-in-out absolute top-0 left-0 w-6 h-6 bg-white border-2 border-gray-600 rounded-full;

  input[type='checkbox']:checked ~ .thumb {
    @apply transform translate-x-full border-green-500;

  input[type='checkbox']:checked ~ .track {
    @apply transform transition-colors bg-green-500;

  input[type='checkbox']:disabled ~ .track {
    @apply bg-gray-500;

  input[type='checkbox']:disabled ~ .thumb {
    @apply bg-gray-100 border-gray-500;

  input[type='checkbox']:focus + .track,
  input[type='checkbox']:active + .track {
    @apply shadow-outline;

  export let id = '';
  export let text = '';
  export let checked = false;
  export let disabled = false;

<label for="{id}">
  <div class="switch">
    <input {id} name="{id}" type="checkbox" class="sr-only" {disabled} bind:checked />
    <div class="track"></div>
    <div class="thumb"></div>
  <span class="ml-2 cursor-pointer">{text}</span>

Enter fullscreen mode Exit fullscreen mode

Now, import Switch into the App.svelte.

<!-- App.svelte -->

  import Switch from './Switch.svelte';

  let uno = false;
  let dos = true;
  let tres = false;
  let quatro = true;

  $: values = { uno, dos, tres, quatro };

<div class="flex items-center justify-center flex-grow h-screen">
  <div class="max-w-xl">
    <h1 class="text-2xl font-semibold text-gray-700">
      Accessible switch toggle with svelte.js + tailwind.css
    <div class="mt-5">
        class="w-full p-2 border border-gray-200"
        placeholder="Tab from here to go to the next switch button"
    <div class="flex justify-between mt-5">
      <Switch bind:checked="{uno}" id="uno" text="uno" />
      <Switch bind:checked="{dos}" id="dos" text="dos" />
      <Switch bind:checked="{tres}" id="tres" text="tres" />
      <Switch bind:checked="{quatro}" disabled="{true}" id="quatro" text="quatro"/>
    <div class="mt-5">
      <pre class="p-4 font-mono bg-teal-100">{JSON.stringify(values)}</pre>

Enter fullscreen mode Exit fullscreen mode

That's it. We can now use tab for navigation, to switch between different buttons, and use space to toggle their state. The secret sauce to why it works is Tailwind's sr-only class where checkbox will be hidden, but still be accessible to screen readers. Accessibility is hard to get right, but that doesn't mean we should ignore it.

You can find the code here. Adjust it to fit your needs and as usual, hope that you learned something new. Thanks for reading!

Top comments (3)

supunkavinda profile image
Supun Kavinda

Hello Ilia, I read most of your articles on Svelte. Do you have an article on sharing states between components in Svelte?

codechips profile image
Ilia Mikhailov Author

Weird. I am actually writing one now and then I just saw your comment. Coming soon :)

supunkavinda profile image
Supun Kavinda

Great! Waiting for it.

This post blew up on DEV in 2020:

js visualized

🚀⚙️ JavaScript Visualized: the JavaScript Engine

As JavaScript devs, we usually don't have to deal with compilers ourselves. However, it's definitely good to know the basics of the JavaScript engine and see how it handles our human-friendly JS code, and turns it into something machines understand! 🥳

Happy coding!