Anyone implemented a nice three-state dark mode toggle?
Love to hear your tips, ideas and even links to examples/code are welcome.<p>This feature is more involved that first look as this HN post unpacks..
https://news.ycombinator.com/item?id=23197966<p>My current wishlist:<p>- Three states (system/light/dark)
- Preference stored for next time
- Two icons light/dark
(click selected icon a second time to 'turn it off' and return to system)
- Vanilla JS/CSS/HTML
- Leans into CSS<p>This implementation comes pretty close.
https://www.bram.us/2020/04/26/the-quest-for-the-perfect-dark-mode-using-vanilla-javascript<p>This post points to a bunch of great three-state dark mode articles in its references.
https://www.brycewray.com/posts/2024/01/its-tri-state-switch-time<p>Sidenote: I found some discussion towards a w3c web preferences API to make this easier but this is far from ready or resolved.<p>https://github.com/WICG/web-preferences-api
https://front-end.social/@kizu/113160248251763608
I started looking at this as I'd like to add one to a few of my sites, but soon started down a rabbit hole:<p>1. Many code examples just handled light/dark and once clicked you cant easily get back to the system setting.<p>2. Seems folks going about this many different ways.<p>3. The Flash of Unstyled Content issue.<p>4. Im a big tailwind fan, but I think a clean implementation should exist just with the most vanilla CSS/HTML and very light use of JS as necessary.<p>5. Storing the preference once set<p>6. Discussions on adding this "simple" (seeming) feature bought out a wall of comments when someone suggested adding it right here on HN, and as of today, HN itself still doesnt have this "simple" feature.
I did once a simple implementation: light, dark and system.
Data was stored in localstorage. The default was system and used quite of bit scss to implement.
Effectivly it consisted of 3 parts: and theming mixing that accepted the background and foreground color, an theme mixin that generated the surrounding "body.$schema" and "@media (prefers-color-scheme: $schema)" and at last an fallback block that only activated when it doesn't support prefers-color-scheme.<p>The javascript was pretty short not even 50 lines and no dependency.
> Anyone implemented a nice three-state dark mode toggle?<p>Anecdotally, I basically never adjust light/dark mode, I pick what I want once and leave it alone forever. (Is this common? Does anyone have telemetry about it?)<p>So the only reason for it to take up prominent real-estate is to ensure it is found at the same initial moment that I want to find it. Something like that could also be done with some kind of quickstart or initial-settings wizard.<p>So my only-half-joking crotchety old-school response would be for a settings screen, with three mutually exclusive option-bullets.
Credit to Ben Schwarz for providing me with this excellent implementation.<p>Supports: Light/Dark/System as well as storing the user preference.
Implements via a simple dropdown select box.<p><a href="https://codepen.io/benschwarz/pen/bGPyboB" rel="nofollow">https://codepen.io/benschwarz/pen/bGPyboB</a>