A simple custom element to toggle between a light and dark page color scheme.
- Toggle between light and dark color schemes
- Respects the user's system color-scheme preference
- Automatically follows system preference changes
- Persists explicit user choices
- Keyboard accessible with Enter and Space
- No dependencies
Install the package from your command line.
npm install color-scheme-switch-elementAdd the custom element to your page and listen for the color-scheme-switch event. The event provides the currently active color scheme, which you can use to update your page accordingly.
Register the event listener before the custom element is defined. This ensures the initial color-scheme-switch event is not missed when the element is registered.
<script>
document.addEventListener('color-scheme-switch', event => {
// The currently active color scheme.
const colorScheme = event.target.value;
// Apply the active color scheme.
document.documentElement.style.setProperty('color-scheme', colorScheme);
// Update the accessible label to describe the action.
event.target.setAttribute('aria-label', `Switch to ${colorScheme === 'light' ? 'dark' : 'light'} color scheme`)
// ...
});
</script>Then load the custom element using a render-blocking module script.
<script type="module" async blocking="render" src="https://cdn.jsdelivr.net/npm/color-scheme-switch-element/+esm"></script>The blocking="render" attribute prevents the page from rendering until the custom element has been registered. This helps prevent a flash of the wrong color scheme during page load.
Add the custom element wherever you want the color-scheme switcher to appear.
<color-scheme-switch title="Toggle light & dark color scheme">
<!-- ... -->
</color-scheme-switch>The element supports light and dark color schemes.
You can also provide an initial value declaratively:
<color-scheme-switch value="dark">
<!-- ... -->
</color-scheme-switch>The initial value is determined in the following order:
- A valid persisted user preference from
localStorage - The
valueattribute - The user's system preference (
prefers-color-scheme)
The persisted preference is stored under the color-scheme localStorage key.
When the user toggles the element, their preference is persisted. If the selected scheme matches the current system preference, the persisted preference is removed so the component can continue following future system preference changes.
If there is no persisted user preference, changes to the system color scheme are automatically reflected by the element.
The current color scheme is available through the value property:
const colorScheme = element.value;
element.value = 'dark';Only light and dark are supported. Assigning any other value throws a TypeError.
Changing value updates the component state and dispatches a color-scheme-switch event. Programmatically assigning value does not persist the preference; persistence only occurs when the user toggles the element.
A color-scheme-switch event is dispatched when the element is initialized and whenever its value changes.
document.addEventListener('color-scheme-switch', event => {
const element = event.target;
const colorScheme = element.value;
// Set page color scheme, update aria-label, icon, etc.
});The event bubbles, so it can be listened for on document or another ancestor.
Assigning the current value does not dispatch an event:
element.value = element.value;The element can be disabled using the disabled attribute:
<color-scheme-switch disabled>
<!-- ... -->
</color-scheme-switch>When disabled, user-triggered toggles are ignored.
When focused, the element responds to:
- Enter
- Space
The element uses role="button" and tabindex="0" by default.
Distributed under the MIT license. See LICENSE for details.