Switch
A switch turns one setting on or off, and the change takes effect the moment someone flips it. Adding icons to the handle, a check or a check and a cross, lets people read the state without relying on the track color. The switches below are live, with and without labels, and some change on a timer.
Reference docs
Choosing a selection control
Four components capture a choice in a form. Each suits a different job:
- Checkbox: one or more options picked from a short list, or a single yes to confirm, such as "I agree to the terms".
- Switch: a setting that takes effect the moment it is flipped, such as Wi-Fi or dark mode.
- Radio buttons: exactly one option from a short list shown in full, such as delivery speed.
- Select: exactly one option from a longer list kept closed until opened, such as country.
Two jobs belong elsewhere. A choice made by clicking a compact tag, such as filtering results, is a filter chip, and a two-state setting in a toolbar is a toggle button.
Built in
puts a check, or a check and a cross, on the handle, so the state does not rest on color alone.icon-selection- The default slot is the label, and a click on the label toggles the switch.
- Space and Enter both toggle the switch, and a focus ring draws on keyboard focus.
,badge-value , andbadge-dot add a badge with no separate element to place.badge-concealed andname set what a form submits while the switch is selected, andform-value makes it invalid while off.form-is-required- Its touch target is at least 48 by 48 pixels even though the switch paints smaller (
).touch-target
Using switches well
- Prefer a switch to a checkbox for settings on a phone.
- Label every switch with the setting it controls, in visible text or in
aria-label. - Add icons only to emphasize the selected state: a check shown while selected, or a check and a cross in both states.
These rules follow Material 3 Expressive's guidance for switches, on material.io.
Touch target
touch-targetoverflowwrappernoneoverflow
Icons
icon-selectionnoneselectedselectedbothnone
Put your own icons in the on-icon and off-icon content, using an cw-iconselected
Badges
badge-valuebadge-dotbadge-concealed
The badge stays out of the switch's accessible name; Names and states says where to put a count that matters.
Forms
A switch in a form submits form-valuenameselectedform-valueon unless you set it. form-is-required
The preview runs in a sandbox that blocks form submission, so the demo shows each switch's state below the form instead. Flip the switches and the state follows; Reset returns them to their authored state.
Disabled
disabled<fieldset> disables the switch too, and disabled
Label position
label-positionleadingtrailingaria-label.
In a settings list
Settings take effect the moment they flip, so a settings list needs no Save button: each row is a switch with a label that states the setting. Keep the labels short, in one position for the whole list, and give each setting its own switch.
Properties
| Property | Attribute | Type | Description |
|---|---|---|---|
badgeConcealed | badge-concealed | booleandefault false | Hides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges. |
badgeDot | badge-dot | booleandefault false | Shows the badge as a small dot with no text, whether or not badgeValue is set. See Badges. |
badgeValue | badge-value | string | The badge's text. While it is empty and badgeDot is not set, no badge renders. Ignored if badgeDot is set. See Badges. |
disabled | disabled | boolean | Whether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled. |
formread-only | HTMLFormElement | The form the component belongs to, or null when it has none. | |
formIsRequired | form-is-required | booleandefault false | When true, require the switch to be selected when participating in form submission.See MDN: checkbox validation. See Forms. |
formValue | form-value | stringdefault on | The value of the switch that is submitted with a form when selected.See MDN: checkbox value. See Forms. |
iconSelection | icon-selectionnone, selected, both | IconSelectionIconSelection.None, .Selected, .Bothdefault IconSelection.None | Sets when the switch's handle shows an icon: never, only while the switch is on, or always. See Icons. |
labelPosition | label-positionleading, trailing | LabelPositionLabelPosition.Leading, .Trailingdefault LabelPosition.Leading | Sets which side of the switch the label is on. See Label position. |
labelsread-only | NodeList | The <label> elements associated with the element. | |
name | name | string | The name the element's value is submitted under with its form. See Forms. |
selected | selected | booleandefault false | Whether the switch is on. A user's toggle updates it, and a form reset restores the state the selected attribute gave it. See Icons, Forms. |
touchTarget | touch-targetnone, overflow, wrapper | TouchTargetTouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configuration | The area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target. |
validationMessageread-only | string | The message describing why the element is invalid, or an empty string when it is valid. | |
validityread-only | ValidityState | The element's ValidityState. | |
willValidateread-only | boolean | Whether the element takes part in constraint validation. False while it is disabled or read-only. |
The value and checked getters are read-only boolean mirrors of selected
Slots
| Slot | Description |
|---|---|
| (default) | The label content. |
on-icon | The icon for the switch's "on" state, replacing the default check mark. It shows only when icon-selection is selected or both. Intended for a cw-icon or equivalent. |
off-icon | The icon for the switch's "off" state, replacing the default close mark. It shows only when icon-selection is both. Intended for a cw-icon or equivalent. |
Events
| Event | Type | Detail | Description |
|---|---|---|---|
change | Event | — | Fired after a user toggles the switch. Setting selected from code does not fire it. It bubbles. |
input | InputEvent | — | Fired as a user toggles the switch. Setting selected from code does not fire it. It bubbles and is composed. |
Methods
| Method | Returns | Description |
|---|---|---|
checkValidity() | boolean | Checks the element's validity and returns true if it is valid. If not, it dispatches an invalid event; nothing changes on screen. |
reportValidity() | boolean | Checks the element's validity and returns true if it is valid. If not, it dispatches a cancelable invalid event and, unless a listener cancels it, shows validationMessage as the field's error text and focuses the field. |
setCustomValidity(error: string) | void | Sets a custom validation message, which makes the element invalid. An empty string clears it. |
Props
| Prop | Type | Description |
|---|---|---|
badgeConcealed | booleandefault false | Hides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges. |
badgeDot | booleandefault false | Shows the badge as a small dot with no text, whether or not badgeValue is set. See Badges. |
badgeValue | string | The badge's text. While it is empty and badgeDot is not set, no badge renders. Ignored if badgeDot is set. See Badges. |
disabled | boolean | Whether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled. |
formread-only (ref) | HTMLFormElement | The form the component belongs to, or null when it has none. |
formIsRequired | booleandefault false | When true, require the switch to be selected when participating in form submission.See MDN: checkbox validation. See Forms. |
formValue | stringdefault on | The value of the switch that is submitted with a form when selected.See MDN: checkbox value. See Forms. |
iconSelection | IconSelectionTypeIconSelection.None, .Selected, .Bothdefault IconSelection.None | Sets when the switch's handle shows an icon: never, only while the switch is on, or always. See Icons. |
labelPosition | LabelPositionTypeLabelPosition.Leading, .Trailingdefault LabelPosition.Leading | Sets which side of the switch the label is on. See Label position. |
labelsread-only (ref) | NodeList | The <label> elements associated with the element. |
name | string | The name the element's value is submitted under with its form. See Forms. |
selected | booleandefault false | Whether the switch is on. A user's toggle updates it, and a form reset restores the state the selected attribute gave it. See Icons, Forms. |
touchTarget | TouchTargetTypeTouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configuration | The area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target. |
validationMessageread-only (ref) | string | The message describing why the element is invalid, or an empty string when it is valid. |
validityread-only (ref) | ValidityState | The element's ValidityState. |
willValidateread-only (ref) | boolean | Whether the element takes part in constraint validation. False while it is disabled or read-only. |
The value and checked getters are read-only boolean mirrors of selected
Children
| Child | Description |
|---|---|
children | The label content. |
a child with slot="on-icon" | The icon for the switch's "on" state, replacing the default check mark. It shows only when iconSelection is selected or both. Intended for a CrIcon or equivalent. |
a child with slot="off-icon" | The icon for the switch's "off" state, replacing the default close mark. It shows only when iconSelection is both. Intended for a CrIcon or equivalent. |
Events
| Prop | Argument | Description |
|---|---|---|
onChange | React.ChangeEvent<HTMLInputElement> | Fired after a user toggles the switch. Setting selected from code does not fire it. It bubbles. |
onInput | React.ChangeEvent<HTMLInputElement> | Fired as a user toggles the switch. Setting selected from code does not fire it. It bubbles and is composed. |
Methods
Call these on the element the ref holds.
| Method | Returns | Description |
|---|---|---|
checkValidity() | boolean | Checks the element's validity and returns true if it is valid. If not, it dispatches an invalid event; nothing changes on screen. |
reportValidity() | boolean | Checks the element's validity and returns true if it is valid. If not, it dispatches a cancelable invalid event and, unless a listener cancels it, shows validationMessage as the field's error text and focuses the field. |
setCustomValidity(error: string) | void | Sets a custom validation message, which makes the element invalid. An empty string clears it. |
Parameters
| Parameter | Type | Description |
|---|---|---|
BadgeConcealed | bool?default false | Hides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges. |
BadgeDot | bool?default false | Shows the badge as a small dot with no text, whether or not BadgeValue is set. See Badges. |
BadgeValue | string? | The badge's text. While it is empty and BadgeDot is not set, no badge renders. Ignored if BadgeDot is set. See Badges. |
Disabled | bool? | Whether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled. |
FormIsRequired | bool?default false | When true, require the switch to be Selected when participating in form submission.See MDN: checkbox validation. See Forms. |
FormValue | string?default on | The value of the switch that is submitted with a form when selected.See MDN: checkbox value. See Forms. |
IconSelection | IconSelection?IconSelection.None, .Selected, .Bothdefault IconSelection.None | Sets when the switch's handle shows an icon: never, only while the switch is on, or always. See Icons. |
LabelPosition | LabelPosition?LabelPosition.Leading, .Trailingdefault LabelPosition.Leading | Sets which side of the switch the label is on. See Label position. |
Name | string? | The name the element's value is submitted under with its form. See Forms. |
TouchTarget | TouchTarget?TouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configuration | The area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target. |
Value | bool | — |
ValueExpression | Expression<Func<bool>>? | Gets or sets an expression that identifies the bound value. |
The value and checked getters are read-only boolean mirrors of selected
Render fragments
Once you write OffIcon or any other fragment as a child element, the main content must go in an explicit <ChildContent> too; markup beside <OffIcon> is a compile error. Here ChildContent is: The label content.
<CbSwitch>
<OffIcon><CbIcon>favorite</CbIcon></OffIcon>
<ChildContent>Main content</ChildContent>
</CbSwitch>
| Parameter | Type | Description |
|---|---|---|
ChildContent | RenderFragment? | The label content. |
OffIcon | RenderFragment? | The icon for the switch's "off" state, replacing the default close mark. It shows only when IconSelection is both. Intended for a CbIcon or equivalent. |
OnIcon | RenderFragment? | The icon for the switch's "on" state, replacing the default check mark. It shows only when IconSelection is Selected or both. Intended for a CbIcon or equivalent. |
Event callbacks
| Parameter | Type | Description |
|---|---|---|
OnChange | EventCallback<ChangeEventArgs> | Fired after a user toggles the switch. Setting Selected from code does not fire it. It bubbles. |
OnInput | EventCallback<ChangeEventArgs> | Fired as a user toggles the switch. Setting Selected from code does not fire it. It bubbles and is composed. |
Inputs
| Input | Type | Description |
|---|---|---|
badgeConcealed | booleandefault false | Hides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges. |
badgeDot | booleandefault false | Shows the badge as a small dot with no text, whether or not badgeValue is set. See Badges. |
badgeValue | string | The badge's text. While it is empty and badgeDot is not set, no badge renders. Ignored if badgeDot is set. See Badges. |
disabled | boolean | Whether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled. |
formIsRequired | booleandefault false | When true, require the switch to be selected when participating in form submission.See MDN: checkbox validation. See Forms. |
formValue | stringdefault on | The value of the switch that is submitted with a form when selected.See MDN: checkbox value. See Forms. |
iconSelection | IconSelectionTypeIconSelection.None, .Selected, .Bothdefault IconSelection.None | Sets when the switch's handle shows an icon: never, only while the switch is on, or always. See Icons. |
labelPosition | LabelPositionTypeLabelPosition.Leading, .Trailingdefault LabelPosition.Leading | Sets which side of the switch the label is on. See Label position. |
name | string | The name the element's value is submitted under with its form. See Forms. |
selected | booleandefault false | Whether the switch is on. A user's toggle updates it, and a form reset restores the state the selected attribute gave it. See Icons, Forms. |
touchTarget | TouchTargetTypeTouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configuration | The area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target. |
value | boolean | — |
The value and checked getters are read-only boolean mirrors of selected
Content projection
| Content | Description |
|---|---|
content with no slot | The label content. |
an element with slot="on-icon" | The icon for the switch's "on" state, replacing the default check mark. It shows only when iconSelection is selected or both. Intended for a CaIcon or equivalent. |
an element with slot="off-icon" | The icon for the switch's "off" state, replacing the default close mark. It shows only when iconSelection is both. Intended for a CaIcon or equivalent. |
Outputs
| Output | Event | Description |
|---|---|---|
cwChange | Event | Fired after a user toggles the switch. Setting selected from code does not fire it. It bubbles. |
cwInput | InputEvent | Fired as a user toggles the switch. Setting selected from code does not fire it. It bubbles and is composed. |
Props
| Prop | Type | Description |
|---|---|---|
badgeConcealed | booleandefault false | Hides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges. |
badgeDot | booleandefault false | Shows the badge as a small dot with no text, whether or not badgeValue is set. See Badges. |
badgeValue | string | The badge's text. While it is empty and badgeDot is not set, no badge renders. Ignored if badgeDot is set. See Badges. |
disabled | boolean | Whether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled. |
formIsRequired | booleandefault false | When true, require the switch to be selected when participating in form submission.See MDN: checkbox validation. See Forms. |
formValue | stringdefault on | The value of the switch that is submitted with a form when selected.See MDN: checkbox value. See Forms. |
iconSelection | IconSelectionTypeIconSelection.None, .Selected, .Bothdefault IconSelection.None | Sets when the switch's handle shows an icon: never, only while the switch is on, or always. See Icons. |
labelPosition | LabelPositionTypeLabelPosition.Leading, .Trailingdefault LabelPosition.Leading | Sets which side of the switch the label is on. See Label position. |
name | string | The name the element's value is submitted under with its form. See Forms. |
selected | booleandefault false | Whether the switch is on. A user's toggle updates it, and a form reset restores the state the selected attribute gave it. See Icons, Forms. |
touchTarget | TouchTargetTypeTouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configuration | The area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target. |
The value and checked getters are read-only boolean mirrors of selected
Slots
| Slot | Description |
|---|---|
default | The label content. |
off-icon | The icon for the switch's "off" state, replacing the default close mark. It shows only when iconSelection is both. Intended for a CvIcon or equivalent. |
on-icon | The icon for the switch's "on" state, replacing the default check mark. It shows only when iconSelection is selected or both. Intended for a CvIcon or equivalent. |
Events
| Event | Type | Description |
|---|---|---|
change | Event | Fired after a user toggles the switch. Setting selected from code does not fire it. It bubbles. |
input | InputEvent | Fired as a user toggles the switch. Setting selected from code does not fire it. It bubbles and is composed. |
Props
| Prop | Type | Description |
|---|---|---|
badgeConcealed | booleandefault false | Hides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges. |
badgeDot | booleandefault false | Shows the badge as a small dot with no text, whether or not badgeValue is set. See Badges. |
badgeValue | string | The badge's text. While it is empty and badgeDot is not set, no badge renders. Ignored if badgeDot is set. See Badges. |
disabled | boolean | Whether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled. |
formIsRequired | booleandefault false | When true, require the switch to be selected when participating in form submission.See MDN: checkbox validation. See Forms. |
formValue | stringdefault on | The value of the switch that is submitted with a form when selected.See MDN: checkbox value. See Forms. |
iconSelection | IconSelectionTypeIconSelection.None, .Selected, .Bothdefault IconSelection.None | Sets when the switch's handle shows an icon: never, only while the switch is on, or always. See Icons. |
labelPosition | LabelPositionTypeLabelPosition.Leading, .Trailingdefault LabelPosition.Leading | Sets which side of the switch the label is on. See Label position. |
name | string | The name the element's value is submitted under with its form. See Forms. |
selected | booleandefault false | Whether the switch is on. A user's toggle updates it, and a form reset restores the state the selected attribute gave it. See Icons, Forms. |
touchTarget | TouchTargetTypeTouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configuration | The area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target. |
The value and checked getters are read-only boolean mirrors of selected
Snippets
| Snippet | Description |
|---|---|
children | The label content. |
onIconSnippet | The icon for the switch's "on" state, replacing the default check mark. It shows only when iconSelection is selected or both. Intended for a CsIcon or equivalent. |
offIconSnippet | The icon for the switch's "off" state, replacing the default close mark. It shows only when iconSelection is both. Intended for a CsIcon or equivalent. |
Events
| Prop | Type | Description |
|---|---|---|
onChange | Event | Fired after a user toggles the switch. Setting selected from code does not fire it. It bubbles. |
onInput | InputEvent | Fired as a user toggles the switch. Setting selected from code does not fire it. It bubbles and is composed. |
A value is what the token defaults to; selecting it copies the token's name.
Tokens
| Token | Value |
|---|---|
--ct-switch-corner-end-end-shape | same as --ct-switch-corner-shape --ct-switch-corner-end-end-shape |
--ct-switch-corner-end-start-shape | same as --ct-switch-corner-shape --ct-switch-corner-end-start-shape |
--ct-switch-corner-shape | --ct-sys-corner-shape --ct-switch-corner-shape |
--ct-switch-corner-start-end-shape | same as --ct-switch-corner-shape --ct-switch-corner-start-end-shape |
--ct-switch-corner-start-start-shape | same as --ct-switch-corner-shape --ct-switch-corner-start-start-shape |
--ct-switch-disabled-handle-color | --ct-sys-color-on-surface --ct-switch-disabled-handle-color |
--ct-switch-disabled-handle-opacity | 0.38 --ct-switch-disabled-handle-opacity |
--ct-switch-disabled-icon-color | --ct-sys-color-surface-container-highest --ct-switch-disabled-icon-color |
--ct-switch-disabled-icon-opacity | 0.38 --ct-switch-disabled-icon-opacity |
--ct-switch-disabled-label-text-color | --ct-sys-color-on-surface --ct-switch-disabled-label-text-color |
--ct-switch-disabled-label-text-opacity | 0.38 --ct-switch-disabled-label-text-opacity |
--ct-switch-disabled-selected-handle-color | --ct-sys-color-surface --ct-switch-disabled-selected-handle-color |
--ct-switch-disabled-selected-handle-opacity | 1 --ct-switch-disabled-selected-handle-opacity |
--ct-switch-disabled-selected-icon-color | --ct-sys-color-on-surface --ct-switch-disabled-selected-icon-color |
--ct-switch-disabled-selected-icon-opacity | 0.38 --ct-switch-disabled-selected-icon-opacity |
--ct-switch-disabled-selected-track-color | --ct-sys-color-on-surface --ct-switch-disabled-selected-track-color |
--ct-switch-disabled-track-color | --ct-sys-color-surface-container-highest --ct-switch-disabled-track-color |
--ct-switch-disabled-track-opacity | 0.12 --ct-switch-disabled-track-opacity |
--ct-switch-disabled-track-outline-color | --ct-sys-color-on-surface --ct-switch-disabled-track-outline-color |
--ct-switch-focus-handle-color | --ct-sys-color-on-surface-variant --ct-switch-focus-handle-color |
--ct-switch-focus-icon-color | --ct-sys-color-surface-container-highest --ct-switch-focus-icon-color |
--ct-switch-focus-track-color | --ct-sys-color-surface-container-highest --ct-switch-focus-track-color |
--ct-switch-focus-track-outline-color | --ct-sys-color-outline --ct-switch-focus-track-outline-color |
--ct-switch-handle-color | --ct-sys-color-outline --ct-switch-handle-color |
--ct-switch-handle-corner-end-end-shape | same as --ct-switch-handle-corner-shape --ct-switch-handle-corner-end-end-shape |
--ct-switch-handle-corner-end-start-shape | same as --ct-switch-handle-corner-shape --ct-switch-handle-corner-end-start-shape |
--ct-switch-handle-corner-shape | same as --ct-switch-corner-shape --ct-switch-handle-corner-shape |
--ct-switch-handle-corner-start-end-shape | same as --ct-switch-handle-corner-shape --ct-switch-handle-corner-start-end-shape |
--ct-switch-handle-corner-start-start-shape | same as --ct-switch-handle-corner-shape --ct-switch-handle-corner-start-start-shape |
--ct-switch-handle-end-end-radius | same as --ct-switch-handle-radius --ct-switch-handle-end-end-radius |
--ct-switch-handle-end-start-radius | same as --ct-switch-handle-radius --ct-switch-handle-end-start-radius |
--ct-switch-handle-height | 16px --ct-switch-handle-height |
--ct-switch-handle-radius | calc(50% - max(0px, var(--_track-height) / 2 - var(--_track-start-start-radius))) --ct-switch-handle-radius |
--ct-switch-handle-start-end-radius | same as --ct-switch-handle-radius --ct-switch-handle-start-end-radius |
--ct-switch-handle-start-start-radius | same as --ct-switch-handle-radius --ct-switch-handle-start-start-radius |
--ct-switch-handle-width | 16px --ct-switch-handle-width |
--ct-switch-hover-handle-color | --ct-sys-color-on-surface-variant --ct-switch-hover-handle-color |
--ct-switch-hover-icon-color | --ct-sys-color-surface-container-highest --ct-switch-hover-icon-color |
--ct-switch-hover-state-layer-color | --ct-sys-color-on-surface --ct-switch-hover-state-layer-color |
--ct-switch-hover-state-layer-opacity | --ct-sys-state-hover-state-layer-opacity --ct-switch-hover-state-layer-opacity |
--ct-switch-hover-track-color | --ct-sys-color-surface-container-highest --ct-switch-hover-track-color |
--ct-switch-hover-track-outline-color | --ct-sys-color-outline --ct-switch-hover-track-outline-color |
--ct-switch-icon-color | --ct-sys-color-surface-container-highest --ct-switch-icon-color |
--ct-switch-icon-size | 16px --ct-switch-icon-size |
--ct-switch-label-gap | 18px --ct-switch-label-gap |
--ct-switch-label-text-color | --ct-sys-color-on-surface --ct-switch-label-text-color |
--ct-switch-label-text-font | --ct-sys-typescale-label-large-font --ct-switch-label-text-font |
--ct-switch-label-text-line-height | --ct-sys-typescale-label-large-line-height --ct-switch-label-text-line-height |
--ct-switch-label-text-size | --ct-sys-typescale-label-large-size --ct-switch-label-text-size |
--ct-switch-label-text-weight | --ct-sys-typescale-label-large-weight --ct-switch-label-text-weight |
--ct-switch-pressed-handle-color | --ct-sys-color-on-surface-variant --ct-switch-pressed-handle-color |
--ct-switch-pressed-handle-height | 28px --ct-switch-pressed-handle-height |
--ct-switch-pressed-handle-width | 28px --ct-switch-pressed-handle-width |
--ct-switch-pressed-icon-color | --ct-sys-color-surface-container-highest --ct-switch-pressed-icon-color |
--ct-switch-pressed-state-layer-color | --ct-sys-color-on-surface --ct-switch-pressed-state-layer-color |
--ct-switch-pressed-state-layer-opacity | --ct-sys-state-pressed-state-layer-opacity --ct-switch-pressed-state-layer-opacity |
--ct-switch-pressed-track-color | --ct-sys-color-surface-container-highest --ct-switch-pressed-track-color |
--ct-switch-pressed-track-outline-color | --ct-sys-color-outline --ct-switch-pressed-track-outline-color |
--ct-switch-selected-focus-handle-color | --ct-sys-color-primary-container --ct-switch-selected-focus-handle-color |
--ct-switch-selected-focus-icon-color | --ct-sys-color-on-primary-container --ct-switch-selected-focus-icon-color |
--ct-switch-selected-focus-track-color | --ct-sys-color-primary --ct-switch-selected-focus-track-color |
--ct-switch-selected-handle-color | --ct-sys-color-on-primary --ct-switch-selected-handle-color |
--ct-switch-selected-handle-height | 24px --ct-switch-selected-handle-height |
--ct-switch-selected-handle-width | 24px --ct-switch-selected-handle-width |
--ct-switch-selected-hover-handle-color | --ct-sys-color-primary-container --ct-switch-selected-hover-handle-color |
--ct-switch-selected-hover-icon-color | --ct-sys-color-on-primary-container --ct-switch-selected-hover-icon-color |
--ct-switch-selected-hover-state-layer-color | --ct-sys-color-primary --ct-switch-selected-hover-state-layer-color |
--ct-switch-selected-hover-state-layer-opacity | --ct-sys-state-hover-state-layer-opacity --ct-switch-selected-hover-state-layer-opacity |
--ct-switch-selected-hover-track-color | --ct-sys-color-primary --ct-switch-selected-hover-track-color |
--ct-switch-selected-icon-color | --ct-sys-color-on-primary-container --ct-switch-selected-icon-color |
--ct-switch-selected-icon-size | 16px --ct-switch-selected-icon-size |
--ct-switch-selected-pressed-handle-color | --ct-sys-color-primary-container --ct-switch-selected-pressed-handle-color |
--ct-switch-selected-pressed-icon-color | --ct-sys-color-on-primary-container --ct-switch-selected-pressed-icon-color |
--ct-switch-selected-pressed-state-layer-color | --ct-sys-color-primary --ct-switch-selected-pressed-state-layer-color |
--ct-switch-selected-pressed-state-layer-opacity | --ct-sys-state-pressed-state-layer-opacity --ct-switch-selected-pressed-state-layer-opacity |
--ct-switch-selected-pressed-track-color | --ct-sys-color-primary --ct-switch-selected-pressed-track-color |
--ct-switch-selected-track-color | --ct-sys-color-primary --ct-switch-selected-track-color |
--ct-switch-state-layer-radius | --ct-sys-corner-radius-full --ct-switch-state-layer-radius |
--ct-switch-state-layer-size | 40px --ct-switch-state-layer-size |
--ct-switch-track-color | --ct-sys-color-surface-container-highest --ct-switch-track-color |
--ct-switch-track-end-end-radius | same as --ct-switch-track-radius --ct-switch-track-end-end-radius |
--ct-switch-track-end-start-radius | same as --ct-switch-track-radius --ct-switch-track-end-start-radius |
--ct-switch-track-height | 32px --ct-switch-track-height |
--ct-switch-track-outline-color | --ct-sys-color-outline --ct-switch-track-outline-color |
--ct-switch-track-outline-width | 2px --ct-switch-track-outline-width |
--ct-switch-track-radius | --ct-sys-corner-radius-full --ct-switch-track-radius |
--ct-switch-track-start-end-radius | same as --ct-switch-track-radius --ct-switch-track-start-end-radius |
--ct-switch-track-start-start-radius | same as --ct-switch-track-radius --ct-switch-track-start-start-radius |
--ct-switch-track-width | 52px --ct-switch-track-width |
--ct-switch-with-icon-handle-height | 24px --ct-switch-with-icon-handle-height |
--ct-switch-with-icon-handle-width | 24px --ct-switch-with-icon-handle-width |
Names and states
A switch is announced with the switch role and follows the WAI-ARIA Authoring Practices: Switch pattern.
- The accessible name is the label in the default slot, or
aria-label. Give a switch without visible text anaria-label. - A
<label for>elsewhere on the page does not name the switch. Use the default slot oraria-label. aria-labelis the only ARIA attribute a switch honors. Any other ARIA attribute you set on it has no effect,aria-invalidincluded. is announced as on or off.selected- A badge is not part of the name, and a dot or concealed badge is hidden from assistive technology. Put a count that matters in the label.
- The switch has no built-in tooltip. A standalone plain or rich tooltip anchored on it describes its focused control, so a screen reader announces that tooltip's text.
Keyboard and focus
| Key | Action |
|---|---|
| Tab | Moves focus to the switch, then past it. |
| Space | Toggles the switch. |
| Enter | Toggles the switch. |
Space and Enter both toggle the switch; a disabled switch ignores both.
- A focus ring draws on keyboard focus only.
removes the switch from the Tab order and blocks toggling, Enter included.disabled
Pointer and touch
- The touch target is at least 48 by 48 pixels, which is above the 24 by 24 pixels WCAG 2.5.8 asks for.
acceptstouch-target ,none , andoverflow .wrapper shrinks the target to the size the switch paints, so check that size before you choose it. Touch target shows each value.none
Display settings
- In forced colors, a selected track fills with
ButtonText, an unselected handle isButtonText, and disabled parts takeGrayText. The on icon isButtonTextand the off icon isCanvas. - With reduced motion requested, the handle slide, the handle resize, and the track and icon transitions take no time.
Standards
With its defaults, the switch meets three WCAG 2.2 success criteria:
Two more depend on how you use it: