Ask HN: Elegant three-state 'Dark mode' toggle, how best to implement?

Anyone implemented a nice three-state dark mode toggle? Love to hear your tips, ideas and even links to examples/code are welcome.

This feature is more involved that first look as this HN post unpacks.. https://news.ycombinator.com/item?id=23197966

My current wishlist:

- 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

This implementation comes pretty close. https://www.bram.us/2020/04/26/the-quest-for-the-perfect-dark-mode-using-vanilla-javascript

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

Sidenote: I found some discussion towards a w3c web preferences API to make this easier but this is far from ready or resolved.

https://github.com/WICG/web-preferences-api https://front-end.social/@kizu/113160248251763608

1 points | by evolve2k 6 hours ago

3 comments

  • stop50 5 hours ago
    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.

    The javascript was pretty short not even 50 lines and no dependency.

    • stop50 5 hours ago
      Today i would do it a lot different. The stages go into layers with the fallback first. The javascript would be splitted in an early part that loads the setting and an later part which does the settings change.
  • Terr_ 5 hours ago
    > Anyone implemented a nice three-state dark mode toggle?

    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?)

    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.

    So my only-half-joking crotchety old-school response would be for a settings screen, with three mutually exclusive option-bullets.

  • evolve2k 6 hours ago
    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:

    1. Many code examples just handled light/dark and once clicked you cant easily get back to the system setting.

    2. Seems folks going about this many different ways.

    3. The Flash of Unstyled Content issue.

    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.

    5. Storing the preference once set

    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.

    • dave4420 5 hours ago
      HN doesn’t have lots of simple features. I wouldn’t read too much into that.