Theme switch
A manual theme switch component for optional light or dark mode viewing.
Requirements (anchor)
Script (anchor)
The script needs to be loaded in the <head> prior to the CSS to negate the FOUC when changing or refreshing pages, you can include it as a linked file or within the document as preferred.
theme-switch.js
The script is also provided uncompressed in the js folder included with the StyleMods source files.
const storageKey = "theme-preference",
onClick = () => {
(theme.value = "light" === theme.value ? "dark" : "light"),
setPreference();
},
getColorPreference = () => (localStorage.getItem(storageKey)
? localStorage.getItem(storageKey)
: window.matchMedia("(prefers-color-scheme: dark)")
.matches ? "dark" : "light"),
setPreference = () => {
localStorage.setItem(storageKey, theme.value),
reflectPreference();
},
reflectPreference = () => {
document.firstElementChild.style.setProperty("color-scheme", theme.value);
},
theme = {
value: getColorPreference()
};
reflectPreference(),
(window.onload = () => {
reflectPreference(),
document.querySelector("#themes").addEventListener("click", onClick);
}),
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", ({matches: e}) => {
(theme.value = e ? "dark" : "light"),
setPreference();
});It's been adapted from Adam Argyle's Building a theme switch component script to apply an inline color-scheme style attribute to the <html> tag as follows depending on the current color-scheme.
// If light
<html lang="en" style="color-scheme: light;">
// If dark
<html lang="en" style="color-scheme: dark;">Button (anchor)
A standard HTML button with the same ID attribute as below is all that's required for the switch.
<button id="themes">Theme switch</button>With just the button and the script you have all the functionality required to manually switch between color-schemes and still respect a users viewing preferences.
Theme switch button (anchor)
Update v1.5.1 The sun and moon icon switch button now uses the new .theme-switch class utility instead of being styled via the ID attribute as was done previously.
The utility only includes the icon property values, the .vis-hidden utility is provided with the accessibility styles and the button will inherit whatever default styles are being used so can be customized as required.
Using the module (anchor)
Load StyleMods as demonstrated (change file path as required) then include the Sass mixin anywhere below, and the script and button as described above:
@use "stylemods/scss" as *;
@include theme-switch-css;See the using modules for information about how to compile the module in cascade layers.
Using the framework (anchor)
Using the recommended custom setup enable the styles in an overrides document:
@use "stylemods/scss/configuration" as *;
$enable-theme-switch: true;Include the overrides and the framework styles with your custom document for compiling the framework:
@use "overrides";
@use "stylemods/scss/stylemods";See using the framework for more information.
Source code (anchor)
The Theme switch source file is included with the components module files, you can view the source code from the latest release (v1.5.1) via the Github link below.
- Source documents
- stylemods/scss/components/theme-switch.scss
- stylemods/js/theme-switch.js
- View on Github
- https://github.com/pmbrown/StyleMods/blob/main/scss/components/theme-switch.scss
- https://github.com/pmbrown/StyleMods/blob/main/js/theme-switch.js
Shared documentation about how to customize the default property values for the styles using the Sass and CSS variables is provided on the customizing page.