Home/Tools/Components/Toggle Switch Generator
Components · Generator

Toggle Switch Generator

Create elegant iOS-style toggle switches with custom colors and animations.

Toggle Settings

20px
Preview:

Preview

Generated CSS & HTML
.switch {
  position: relative;
  display: inline-block;
  width: 40px;
  height: 20px;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #e5e7eb;
  transition: .4s;
  border-radius: 20px;
}

.slider:before {
  position: absolute;
  content: "";
  height: 16px;
  width: 16px;
  left: 2px;
  bottom: 2px;
  background-color: white;
  transition: .4s;
  border-radius: 50%;
}

input:checked + .slider {
  background-color: #0071e3;
}

input:checked + .slider:before {
  transform: translateX(16px);
}

100%
Free, no
sign-up needed
0
Code written
by hand
85+
CSS tools
in one place
<1s
Copy-ready
CSS instantly
What is this

What is the CSS Toggle Switch Generator?

Build custom CSS toggle switches with smooth animations. Accessible markup included with every generated style.

Everything runs locally in your browser. Adjust the controls above, preview instantly, and copy clean, production-ready CSS — no account, no upload.

How to use

Using the CSS Toggle Switch Generator

Everything lives in the panel at the top of this page. There is nothing to install — it all runs right here in your browser.

1

Set toggle dimensions

Adjust the track width and height. The thumb diameter is automatically calculated at 75% of the track height with equal margins.

2

Choose colours

Set the off-state and on-state track colours. The thumb colour defaults to white.

3

Copy the HTML and CSS

The generator outputs both the CSS and the minimal HTML markup. Use them together for a working accessible toggle.

The output

What the generated code looks like

Clean, production-ready CSS — no vendor bloat, no unnecessary declarations.

toggle.css
.toggle {
  position: relative;
  display: inline-block;
  width: 48px;
  height: 28px;
}

.toggle input {
  opacity: 0;
  width: 0;
  height: 0;
}

.toggle-slider {
  position: absolute;
  inset: 0;
  background: #ccc;
  border-radius: 28px;
  cursor: pointer;
  transition: background 0.2s;
}

.toggle-slider::before {
  content: '';
  position: absolute;
  width: 20px;
  height: 20px;
  left: 4px;
  top: 4px;
  background: #fff;
  border-radius: 50%;
  transition: transform 0.2s;
}

input:checked + .toggle-slider {
  background: #0071e3;
}

input:checked + .toggle-slider::before {
  transform: translateX(20px);
}

The actual input is hidden with opacity: 0 (not display: none) so it remains focusable and keyboard-operable. Screen readers read the input label, not the visual slider.

Common mistakes & fixes

Common mistakes & how to fix them

A few habits trip people up. Here is what to watch for — and the exact fix.

Hiding input with display:none breaks accessibility

display: none removes the element from the accessibility tree. Screen readers cannot read a toggle with a hidden input.

Fix: Use opacity: 0; width: 0; height: 0 to visually hide the input while keeping it focusable.

Missing label element

A toggle without an associated label has no accessible name.

Fix: Wrap the input and slider in a <label> element, or use aria-label on the input.

Pro tips

Pro tips for better results

Add :focus-visible to the slider for keyboard users

When the hidden input is focused via keyboard, add a visible outline to .toggle-slider using the :has selector: .toggle:has(input:focus-visible) .toggle-slider { outline: 2px solid #0071e3; }

FAQ

Frequently asked questions

Access the checked property of the input element: document.querySelector(".toggle input").checked. Or listen to the change event.
Yes. Replace transition: transform 0.2s with transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1). The overshoot cubic-bezier creates a spring bounce.

From the blog

Read more