Switch
Turns a setting on or off at once.
Checked
falsedefault
true
Sizes
sm
defaultdefault
States
rest
hover
held
focus-visible
on
pending
invalid
disabled
Usage
When to use it
- Use
- A setting takes effect at once, with no Save button: a tool on or off, logging, notifications.
- Use
- A list of independent settings, each saved on its own.
- Not for
- The choice is saved with a form. Use Checkbox.
- Not for
- Two to five views of the same thing. Use Segmented control.
- Not for
- The action starts something rather than setting a state. Use Button.
Rules
6 rules
- Must
- Apply the change on onCheckedChange; never put a Switch in a form that waits for Save. Because a switch promises the change happened, so a Save button after it leaves the person unsure which one counted.
- Must
- Pass pending while the change saves, and set checked back if it fails, with the reason beside it. Because pending holds the switch read-only so a second flip cannot race the first, and a switch left on after a failed save lies.
- Must
- Name the switch with a FieldLabel in a horizontal Field, or aria-label. Because a bare switch is announced as "switch, on" with nothing to say what is on.
- Never
- Write the state into the label ("On", "Enabled") or change the label when it flips. Because the knob already shows the state and a screen reader says it, so a changing label reads as a different setting.
- Never
- Colour the track green or the knob in a hue when on. Because colour means status in Glaze; on reads from the small glaze track and the knob's place.
- Should
- Use size="sm" in a dense list of 36px rows, the default beside a label and description.
State order
7 states, highest first
- 1
- disabled
- 2
- pending
- 3
- invalid
- 4
- held
- 5
- focus-visible
- 6
- hover
- 7
- rest
Accessibility
4 checks
- role="switch" with aria-checked, named by its label; pending sets aria-busy and keeps focus.
- On is shown by the small glaze track and the knob's place, not by a hue; the knob's ring marks it on the grey off track.
- The hit area reaches 28px around a 20px switch.
- Announce a failed save in text beside the switch, not only by the knob moving back.
Keyboard
2 keys
- Space
- Flips the switch.
- Enter
- Flips the switch.
Edge cases
7 edge cases
- Save fails
- The caller sets checked back; the knob returns and the reason shows beside it.
- Double press while saving
- Pending makes it read-only, so the second press is ignored.
- Right to left
- The knob starts at the right and moves left when on.
- Dark theme
- Off is a light knob on light ink at 15%; on, the track is light glaze and the knob dark.
- Disabled
- The track drops to the flat grey field and the knob's ring fades.
- Forced colors
- The track draws a CanvasText border and turns Highlight when on; the knob is CanvasText.
- Reduced motion
- The knob jumps instead of gliding.
API
5 props
checked, defaultChecked, onCheckedChangeBase UI Switchsize'sm' | 'default'default'default'pendingbooleandefaultfalsearia-invalidbooleandefaultfalsedisabled, readOnly, nameBase UI
Tokens
19 tokens
--switch-off- rgb(5 5 5 / 0.10)
--switch-knob- #ffffff
--field- #efefef
--line-control- rgb(5 5 5 / 0.15)
--line-faint- rgb(5 5 5 / 0.06)
--fail- #e35e49
--text-2- rgb(5 5 5 / 0.60)
--glaze-sm-top- #6b6b6b
--glaze-sm-mid- #3d3d3d
--glaze-sm-bottom- #232323
--glaze-sm-highlight- rgb(255 255 255 / 0.30)
--glaze-sm-rim- rgb(0 0 0 / 0.55)
--glaze-sm-text- rgb(255 255 255 / 0.92)
--focus-width-sm- 1.5px
--radius-pill- 999px
--scale-press- 0.97
--dur-state- 160ms
--ease-out- cubic-bezier(0.2, 0.8, 0.2, 1)
--focus- rgb(5 5 5 / 0.80)