What is Nostr?
Terence Eden’s Blog /
npub1lyw…ruez
2023-10-26 11:34:02

Terence Eden’s Blog on Nostr: CSS only colour-scheme selector - no JS required ...

CSS only colour-scheme selector - no JS required
https://shkspr.mobi/blog/2023/10/css-only-colour-scheme-selector-no-js-required/

Yesterday I wrote about a lazy way to implement a manual dark mode chooser. Today I'll show you a slightly more sensible way to do it. It just uses CSS, no need for JavaScript.

Here's a scrap of HTML which present a dropdown for a user to choose their colour scheme:<select id="colour-mode"> <option value="">Theme Selector</option> <option value="dark">Dark Mode</option> <option value="light">Light and Bright</option> <option value="eink">eInk</option></select>

It will look something like this:
Theme SelectorDark ModeLight and BrighteInk

Modern CSS gives us a way to see which of those options have been chosen by the user:#colour-mode option:checked[value="dark"]

That can be combined with the new :has() CSS pseudo class. This allows the CSS to say "If the body has a checked elements with this specific value, then apply these CSS rules" - like so:body:has( > #colour-mode option:checked[value="dark"] ) { background: ...}

OK! So, depending on which option the user selects, the CSS can be made to do all sorts of weird and wonderful things. But, that will require...CSS variables

Here's some CSS which will set various colours for light mode and dark mode. Then it sets the default colours to the light mode::root { /* Light mode variables */ --light-background: beige; --light-text: #000; --light-bg: #0F0; /* Dark mode variables */ --dark-background: #000; --dark-text: #FFF; --dark-bg: #FF0; /* Default variables */ --background: var(--light-background); --text: var(--light-text); --bg: var(--light-bg);}

So the rest of the CSS can have things like:p { color: var(--text);}

The <p> will be set to use the colour from --text which, at first, is the same as --light-text.

That can be changed with both :has() and :checked like so:body:has( > #colour-mode option:checked[value="dark"] ) { --text: var(--dark-text);}

That says "If the body element has a child which has the ID "colour-mode", and if "colour-mode" has a child option with the checked value of "dark", then set the --text variable to be the value of --dark-text.

String enough of those together and that will make a pretty capable theme switcher!User Preferences

Some browsers will know whether their user has a preference for dark or light mode. Perhaps the user has set their phone to dark mode, or flipped a switch somewhere for light mode. This preference can be determined in CSS using the prefers-color-scheme media feature.

A site can set the default value of the colour variables like so:@media (prefers-color-scheme: light) { :root { --text: var(--light-text); }}@media (prefers-color-scheme: dark) { :root { --text: var(--dark-text); }}Demo

Caveats

A few issues:

This doesn't yet work on Firefox. Even if you enable layout.css.has-selector.enabled in about:config. Support is coming soon™.
This doesn't remember your user's choice. So they'll need to toggle it on every page load.
Choosing a sensible colour scheme means you should test it for accessibility.Saving the selection

Sadly, this does require JS. This uses localstorage rather than a cookie. If a user doesn't have JS enabled, this will gracefully degrade; the theme will follow the user's preferences, switching will work but won't be remembered.// Get the theme switchervar themeSelect = document.getElementById('theme');// If a theme has previously been selected, set itif (localStorage.theme) { themeSelect.value = localStorage.theme;}// Listen for any changes and save themif(themeSelect) { themeSelect.addEventListener('change', function(event){ localStorage.setItem('theme', themeSelect.value); });}Further Reading

Do you know color-scheme?
How to Make Dark Mode for Websites Using Only CSS
Prefers Color Scheme
Pure CSS dark mode toggle switcher
How to store theme color preferences using the Local Storage API

https://shkspr.mobi/blog/2023/10/css-only-colour-scheme-selector-no-js-required/

#css #HTML
Author Public Key
npub1lywey3rjuskr7kstpvwj3xafa56qrkfc6r7f665rxvw4sv2jw6ps5vruez