A binary toggle painted as a sliding pill. Markup is a regular
<input type="checkbox"> with the .switch
class so it keeps the checkbox keyboard contract; the thumb is a
positioned ::before that translates on :checked.
Add role="switch" and aria-checked so AT
announces the switch idiom rather than "checkbox".
Thumb translation + colour swap easing. Honoured under prefers-reduced-motion: reduce (transition zeroed).
Override example
app.scss
@use '@adnap/krysalicss/element/switch' with ( $width: 2.75rem, $height: 1.5rem, $track-mix: 35%,);
Tokens consumed
Token
Used for
--kc-primary-bg / --kc-primary-fg
Checked-state track fill, border, and thumb fill.
--kc-fg
Off-state thumb fill (highest available contrast against the track tint).
--kc-focus-ring
Painted on :focus-visible. Falls back to --kc-fg then currentColor.
Accessibility
Markup is still a native checkbox, so keyboard activation (Space), label-click toggling, and form-submission semantics ship for free.
Add role="switch" and bind aria-checked to the input's checked state so screen readers announce "switch, on/off" rather than "checkbox, checked/unchecked".
State is conveyed by both fill colour and thumb position, so the cue isn't colour-only (WCAG 1.4.1).
The transition is short ($global-transition-duration, 120ms) and disabled under prefers-reduced-motion: reduce.
Forced-colors mode remaps fills to ButtonFace / CanvasText off, Highlight / HighlightText on so the toggle still reads under Windows High Contrast.
The 1.25rem × 2.25rem track is below the WCAG 2.5.5 (44 × 44 px) touch-target floor. Wrap the input in a <label> whose hit-area meets the floor.
See also
Checkbox — same <input type="checkbox"> markup without the .switch class.