Switch

A track-and-thumb toggle for on / off settings.

Basic

Add .switch to an <input type="checkbox" role="switch">. Pair with a label the same way as Checkbox or Radio; role="switch" makes assistive tech announce the affordance correctly.

Large

Add .switch--lg for a larger variant, suited to standalone settings rows where the switch is the row's primary affordance.

Settings row

Push the switch to the row's trailing edge with a plain flex row. The label sits on the left as row content; the switch pins right as the affordance.

Disabled

Add disabled to dim the input and its label, and block interaction.

Without label

The .switch input stands on its own. Always pair with an aria-label.

Browser validation

Pair required with the native :user-invalid pseudo. The browser fires it after the user interacts with the field, and clears it the moment the switch is on. Use for inline validation where the affordance owns its own state.

The track looks valid until you interact. Click it once then click away to trigger :user-invalid. Toggle it on and the red clears.

Server validation

Set aria-invalid="true" from your form library. The track fill follows the on/off semantic; the border carries the invalid signal, so both compose at once.

Customization

These variables retune .switch without touching component CSS. Override on the switch, a parent scope, or :root.

VariableUse
--switch-track-widthTrack width; the lg variant reassigns this
--switch-track-heightTrack height
--switch-thumb-sizeThumb diameter
--switch-insetVisible gap between thumb edge and track edge
--switch-radiusTrack corner radius; pill by default, set a smaller value to flatten
--switch-off-bgOff-state track; a mid-gray that adapts per theme so the white thumb stays readable in both modes
--switch-on-bgOn-state track
--switch-thumb-colorThumb fill (white literal so it reads on both track states in both themes)
--switch-thumb-paintThumb shape; default is a radial-gradient circle, swap to a linear-gradient for a square thumb