← Back to gallery
CSS

Toggle Switch Appearance None

A native checkbox skinned as a switch via appearance: none, with a sliding thumb driven by :checked and a focus-visible ring layered above the track.

Duration
1s
Resolution
1440×900
Format
CSS
toggleswitchcheckboxappearance-nonethumb-slide

Form / appearance: none / native checkbox

Toggle switch appearance none

Reimplements a switch using a real input checkbox with appearance: none, redrawing the track and thumb in CSS while keeping Space/Enter toggling and focus-visible rings from the native element.

compact36×20, thumb 14

Settings row switch

Compact

A 36×20 switch tuned for settings rows. The thumb slides across a short track and the track color shifts to signal the active state.

  • compact
  • settings
  • keyboard

Mobile-first switch

Pill

A 48×26 pill switch tuned for thumb-friendly mobile tap targets, with a longer track and a larger thumb that keeps visible state stable.

  • pill
  • touch
  • mobile

Emphasis state switch

Tall Rocker

A 56×32 rocker switch for moments where the choice deserves visual weight, like enabling a paid plan or toggling destructive modes.

  • tall
  • weighty
  • emphasis

Toggle inspector

Compact

Click the switch or press Space with it focused.

Track
36×20px
Thumb travel
18px

Native checkbox semantics are preserved — keyboard Space/Enter toggle, assistive tech reads state, and :focus-visible shows an outline.

css
.switch {
  appearance: none;
  width: 36px;
  height: 20px;
  background: rgba(148, 163, 184, 0.4);
  border-radius: 999px;
  cursor: pointer;
  position: relative;
  transition: background 0.18s ease;
}

.switch::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: white;
  transition: transform 0.18s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.switch:checked {
  background: #7dd3fc;
}

.switch:checked::after {
  transform: translateX(18px);
}

.switch:focus-visible {
  outline: 2px solid #7dd3fc;
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .switch, .switch::after { transition-duration: 0s; }
}