Tailwind CSS cookbook · Intermediate
Style a toggle switch from a checkbox
Turn a checkbox into an accessible on/off switch with a sliding knob.
Approach
Keep a real checkbox (for keyboard and screen readers) but visually hide it with sr-only peer. Style a sibling
track with peer-checked: and move the knob with peer-checked:translate-x-5.
Solution
<label class="m-6 inline-flex cursor-pointer items-center gap-3">
<input type="checkbox" role="switch" class="peer sr-only" checked>
<span class="relative h-6 w-11 rounded-full bg-slate-300 transition peer-checked:bg-emerald-500 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-emerald-600 after:absolute after:top-0.5 after:left-0.5 after:size-5 after:rounded-full after:bg-white after:shadow after:transition peer-checked:after:translate-x-5"></span>
<span class="text-sm font-medium">Email notifications</span>
</label>
Pitfalls
- Using
hiddeninstead ofsr-onlyon the checkbox; it can no longer be focused or announced. - No focus style on the visible track; use
peer-focus-visible:.
Variations
- Headless UI's Switch component provides the same in React and Vue.
Further reading: Tailwind CSS docs
Reference: https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-sibling-state