Switch
<quiet-switch>
Toggles a setting between on and off with an immediate effect, serialized for form submission. Use a switch for preferences like notifications, dark mode, and airplane mode where the change applies right away and does not need a separate save step.
<quiet-switch name="mode" value="kitten">Kitten mode</quiet-switch>
Examples Jump to heading
Labels and descriptions Jump to heading
The switch's label is provided via its default slot. You can use the description attribute to
provide a plain text description. If you want to provide HTML, use the description slot
instead.
<quiet-switch name="notifications" value="enabled"> Enable notifications <span slot="description"> Get updates when your cat takes a nap. <a href="#">Learn more</a> </span> </quiet-switch>
Checked initially Jump to heading
Add the checked attribute to check the switch initially.
<quiet-switch name="mode" value="kitten" checked>Kitten mode</quiet-switch>
Adding inner labels Jump to heading
Use the on and off slots to show inner labels or icons that align with the
switch's checked state. Space is very limited, so make sure the labels are short enough to fit.
<quiet-switch name="mode" value="kitten"> Kitten mode <span slot="on-label">on</span> <span slot="off-label">off</span> </quiet-switch> <quiet-switch name="mode" value="kitten"> Kitten mode <quiet-icon slot="on-label" name="check" label="On"></quiet-icon> <quiet-icon slot="off-label" name="x" label="Off"></quiet-icon> </quiet-switch>
Changing the size Jump to heading
Use the size attribute to change the text field's size.
<quiet-switch size="xs">Extra small</quiet-switch> <quiet-switch size="sm">Small</quiet-switch> <quiet-switch size="md">Medium</quiet-switch> <quiet-switch size="lg">Large</quiet-switch> <quiet-switch size="xl">Extra large</quiet-switch>
Disabling Jump to heading
Use the disabled attribute to disable the switch.
<quiet-switch disabled>Unchecked and disabled</quiet-switch><br> <quiet-switch checked disabled>Checked and disabled</quiet-switch>
Validation Jump to heading
The required attribute can be applied to enable validation using the
Constraint Validation
. This will prevent form submission until the switch is checked.
<form action="about:blank" method="get" target="_blank"> <quiet-switch name="sleep" value="zzz" required>Sleep mode</quiet-switch> <br><br> <quiet-button type="submit" variant="primary">Submit</quiet-button> <quiet-button type="reset">Reset</quiet-button> </form>
Using custom validation Jump to heading
Use the setCustomValidity() method to make the switch invalid and show a custom error message
on submit. This will override all other validation parameters. To clear the error, remove the attribute or
set it to an empty string.
<form action="about:blank" method="get" target="_blank" id="switch__custom-validation"> <quiet-switch name="sleep" value="zzz" required>Sleep mode</quiet-switch> <br><br> <quiet-button type="submit" variant="primary">Submit</quiet-button> <quiet-button type="reset">Reset</quiet-button> </form> <script type="module"> import { allDefined } from '/dist/quiet.js'; await allDefined(); const form = document.getElementById('switch__custom-validation'); const toggle = form.querySelector('quiet-switch'); toggle.setCustomValidity('Have you taken a nap first?'); </script>
Styling validation Jump to heading
You can style valid and invalid switches using the user-valid and user-invalid
custom states. These styles are only shown after the user interacts
with the form control or when the form is submitted. The :valid and
:invalid pseudo classes are also available, but they match even before the user has had a
chance to fill out the form.
<form action="about:blank" method="get" target="_blank" class="switch__validation-custom"> <quiet-switch name="sleep" value="zzz" required>Sleep mode</quiet-switch> <br><br> <quiet-button type="submit" variant="primary">Submit</quiet-button> <quiet-button type="reset">Reset</quiet-button> </form> <style> .switch__validation-custom { quiet-switch:state(user-valid) { outline: solid 2px var(--quiet-constructive-stroke-mid); outline-offset: .5rem; } quiet-switch:state(user-invalid) { outline: solid 2px var(--quiet-destructive-stroke-mid); outline-offset: .5rem; } } </style>
If you're using the CSS utilities, add the
quiet-user-valid and quiet-user-invalid classes to any form control for
automatic validation styling.
Styling switches Jump to heading
Switches have a minimal default appearance, but the CSS parts and design tokens
give you full control over how they look. The track color for each state is determined by design tokens, so
the cleanest way to recolor a switch is to override them. The on state uses
--quiet-primary-fill-mid and the off state uses --quiet-neutral-fill-soft. Because
these tokens adapt to the current color scheme, the switch stays legible in both light and dark mode.
<quiet-switch class="switch__success" checked>Auto-renew subscription</quiet-switch> <quiet-switch class="switch__success">Auto-renew subscription</quiet-switch> <style> .switch__success { --quiet-primary-fill-mid: var(--quiet-constructive-fill-mid); --quiet-neutral-fill-soft: var(--quiet-neutral-fill-mid); } </style>
For everything else, reach for the parts. The visual-box part wraps the track and exposes
--height and --width custom properties that scale and stretch the switch, while
the thumb part is the sliding knob. Combine these with the track tokens and you can build
something completely bespoke. Here's a KDE-inspired theme toggle: a deep cobalt-slate night, a vivid
Breeze-blue day, a recessed track, and a glossy handle with inner icons that swap as it slides. The colors
are fixed values, so it looks identical in light and dark mode.
<quiet-switch class="switch__kde" checked> Theme <quiet-icon slot="on-label" family="filled" name="moon"></quiet-icon> <quiet-icon slot="off-label" family="filled" name="sun"></quiet-icon> </quiet-switch> <style> .switch__kde { /* Track colors for each state */ --quiet-neutral-fill-soft: #3daee9; /* day — Breeze blue */ --quiet-primary-fill-mid: #243b5e; /* night — deep cobalt slate */ /* Match the focus ring to the theme */ --quiet-focus-color: #3daee9; /* Size and shape, with a softly recessed track */ &::part(visual-box) { --height: 2em; --width: 3.75em; box-shadow: inset 0 1px 3px rgb(0 0 0 / 0.25), inset 0 0 0 1px rgb(0 0 0 / 0.08); } /* A glossy, modern handle */ &::part(thumb) { background: linear-gradient(180deg, #ffffff, #dfe6ef); box-shadow: 0 1px 2px rgb(0 0 0 / 0.3), inset 0 1px 0 rgb(255 255 255 / 0.7); } /* Inner icon colors */ &::part(on-label) { color: #cdd9f0; /* cool moonlight */ } &::part(off-label) { color: #fde68a; /* warm sunlight */ } } </style>
Keyboard support Jump to heading
Tab to the switch to focus it, then use the keys below.
| Key | Action |
|---|---|
| Space Enter | Toggles the switch on or off |
API Jump to heading
Importing Jump to heading
The autoloader is the recommended way to import components but, if you prefer to do it manually, the following code snippets will be helpful.
To manually import <quiet-switch> from the CDN, use the following code.
import 'https://cdn.quietui.org/v5.3.1/components/switch/switch.js';
To manually import <quiet-switch> from a self-hosted distribution, use the following
code. Remember to replace /path/to/quiet with the appropriate local path.
import '/path/to/quiet/components/switch/switch.js';
Slots Jump to heading
Switch supports the following slots. Learn more about using slots
| Name | Description |
|---|---|
| (default) |
The switch's label. For plain-text labels, you can use the label attribute instead.
|
description
|
The switch's description. For plain-text descriptions, you can use the
description attribute instead.
|
off-label
|
The label to show when the switch is off. |
on-label
|
The label to show when the switch is on. |
Properties Jump to heading
Switch has the following properties that can be set with corresponding attributes. In many cases, the attribute's name is the same as the property's name. If an attribute is different, it will be displayed after the property. Learn more about attributes and properties
| Property | Description | Reflects | Type | Default |
|---|---|---|---|---|
label
|
The switch's label. If you need to provide HTML in the label, use the label slot
instead.
|
|
string
|
|
description
|
The switch's description. If you need to provide HTML in the description, use the
description slot instead.
|
|
string
|
|
name
|
The name of the switch. This will be submitted with the form as a name/value pair. |
|
string
|
|
value
|
The switch's value. |
|
string
|
''
|
checked
|
The switch's checked state. |
|
boolean
|
false
|
disabled
|
Disables the switch. |
|
boolean
|
false
|
size
|
The switch's size. |
|
'xs' |
'sm' |
'md' |
'lg' |
'xl'
|
'md'
|
form
|
The form to associate this control with. If omitted, the closest containing
<form> will be used. The value of this attribute must be an ID of a form in the
same document or shadow root.
|
|
string
|
|
required
|
Makes the switch required. Form submission will not be allowed until the switch is checked. |
|
boolean
|
false
|
Methods Jump to heading
Switch supports the following methods. You can obtain a reference to the element and call them like functions in JavaScript. Learn more about methods
| Name | Description | Arguments |
|---|---|---|
focus() |
Sets focus to the switch. | |
blur() |
Removes focus from the switch. | |
checkValidity() |
Checks if the form control has any restraints and whether it satisfies them. If invalid,
false will be returned and the invalid event will be dispatched. If valid,
true will be returned.
|
|
reportValidity() |
Checks if the form control has any restraints and whether it satisfies them. If invalid,
false will be returned and the invalid event will be dispatched. In
addition, the problem will be reported to the user. If valid, true will be returned.
|
|
setCustomValidity()
|
Sets a custom validation message for the form control. If this message is not an empty string, then the form control is considered invalid and the specified message will be displayed to the user when reporting validity. Setting an empty string clears the custom validity state. | message: string |
Events Jump to heading
Switch dispatches the following custom events. You can listen to them the same way was native events. Learn more about custom events
| Name | Description |
|---|---|
quiet-blur |
Emitted when the switch loses focus. This event does not bubble. |
quiet-change |
Emitted when the user commits changes to the switch's value. |
quiet-focus |
Emitted when the switch receives focus. This event does not bubble. |
quiet-input |
Emitted when the switch receives input. |
CSS parts Jump to heading
Switch exposes internal elements that can be styled with CSS using the selectors shown below. Learn more about CSS parts
| Name | Description | CSS selector |
|---|---|---|
label |
The <label> that wraps the entire control. |
::part(label)
|
description |
The element that contains the switch's description. |
::part(description)
|
visual-box |
The element that wraps the internal switch. |
::part(visual-box)
|
switch |
The internal switch, an
<input type="checkbox" role="switch"> element.
|
::part(switch)
|
thumb |
The switch's thumb. |
::part(thumb)
|
on-label |
The container wrapping the on-label. |
::part(on-label)
|
off-label |
The container wrapping the off-label. |
::part(off-label)
|
Custom States Jump to heading
Switch has the following custom states. You can target them with CSS using the selectors shown below. Learn more about custom states
| Name | Description | CSS selector |
|---|---|---|
disabled |
Applied when the switch is disabled. |
:state(disabled)
|
focused |
Applied when the switch has focus. |
:state(focused)
|
user-valid |
Applied when the switch is valid and the user has sufficiently interacted with it. |
:state(user-valid)
|
user-invalid |
Applied when the switch is invalid and the user has sufficiently interacted with it. |
:state(user-invalid)
|
Dependencies Jump to heading
Switch automatically imports the following elements. Sub-dependencies are also included in this list.