Toggle / Switch
<button role="switch">
A binary control for enabling or disabling a setting. More visually expressive than a checkbox.
Overview
Preview
Basic toggle
Preview
Enabled
html
<!-- On -->
<button
role="switch"
aria-checked="true"
class="relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent bg-[#D40C37] transition-colors duration-200 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-[#D40C37]/50 focus-visible:ring-offset-2 focus-visible:ring-offset-zinc-950"
>
<span class="pointer-events-none inline-block h-5 w-5 translate-x-5 transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out" />
</button>
<!-- Off -->
<button
role="switch"
aria-checked="false"
class="... bg-zinc-700"
>
<span class="... translate-x-0" />
</button>With Vue reactivity
vue
<script setup>
import { ref } from 'vue'
const enabled = ref(false)
</script>
<template>
<button
role="switch"
:aria-checked="enabled"
@click="enabled = !enabled"
:class="['relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-[#D40C37]/50 focus-visible:ring-offset-2 focus-visible:ring-offset-zinc-950',
enabled ? 'bg-[#D40C37]' : 'bg-zinc-700']"
>
<span :class="['pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out',
enabled ? 'translate-x-5' : 'translate-x-0']"
/>
</button>
</template>With Headless UI (recommended for production)
vue
<script setup>
import { Switch } from '@headlessui/vue'
import { ref } from 'vue'
const enabled = ref(false)
</script>
<template>
<Switch
v-model="enabled"
:class="['relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-[#D40C37]/50 focus-visible:ring-offset-2 focus-visible:ring-offset-zinc-950',
enabled ? 'bg-[#D40C37]' : 'bg-zinc-700']"
>
<span :class="['pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow-lg transition duration-200',
enabled ? 'translate-x-5' : 'translate-x-0']"
/>
</Switch>
</template>Accessibility notes
- Use
role="switch"witharia-checkedfor state - Always pair with a visible label or
aria-label - The
disabledattribute should also addaria-disabled="true" - Headless UI's
<Switch>handles all ARIA and keyboard interaction automatically