Toggle Switch
An accessible iOS-style toggle switch built on a real checkbox, so it works with the keyboard, forms and screen readers with no JavaScript.
The code
Plain HTML and CSS with no dependencies. Copy a single file, or choose "Full file" for a complete page you can save as index.html and open in a browser.
<div class="settings">
<label class="row">
<span>Email notifications</span>
<input type="checkbox" class="switch" checked />
</label>
<label class="row">
<span>Dark mode</span>
<input type="checkbox" class="switch" />
</label>
<label class="row">
<span>Weekly summary</span>
<input type="checkbox" class="switch" disabled />
</label>
</div>The AI prompt
Paste this into an AI coding tool to generate the same component, then ask it to adapt the colours, text or framework to your project.
Create an accessible toggle switch component using only HTML and CSS. Requirements: - Use a real <input type="checkbox"> with appearance: none so the checkbox itself is restyled as the switch. Do not hide the input and fake it with a span. - Track: 48px by 28px, fully rounded, grey #cfd3e1 when off, indigo #2506ad when :checked, with a 0.25s background transition. - Thumb: a ::before pseudo-element, 22px white circle with a small shadow, 3px inset, that slides 20px right when checked (transform: translateX). - Focus: a 3px orange outline on :focus-visible. - Disabled: 45% opacity and a not-allowed cursor. - Demo: a white settings card with three labelled rows (Email notifications - on, Dark mode - off, Weekly summary - disabled). Wrap each row in a <label> so clicking the text toggles the switch. Return one HTML file with a <style> block.
How to build it, step by step
- 1
Start with a real checkbox. You keep keyboard support (Space to toggle), form submission and screen-reader semantics for free.
- 2
Remove the native look with appearance: none, then size and round the input to make the track.
- 3
Draw the thumb with a ::before pseudo-element positioned inside the track.
- 4
Use the :checked pseudo-class to change the track colour and slide the thumb with a transform.
- 5
Wrap the text and input in a label so the whole row is clickable.
- 6
Style :focus-visible and :disabled states; they are part of a complete form control.
Customisation tips
- Add role='switch' to the input if you want screen readers to announce on/off instead of checked/unchecked.
- Change the track width to 56px and translateX to 28px for a larger touch target.
- In React, control it with the checked and onChange props like any checkbox.