How I added color mode support to my little Astrosite.
One of my latest Astro adventures was adding a dark mode toggle1—actually a light mode for this site. I’m using Tailwind and mostly stole Kevin Zuniga Cuellar’s approach with two key differences:
I only save the user’s color mode choice when it differs from their system preference.
I used Vue for the theme switch component instead of Preact. (Though I’ll probably switch to Svelte for fun and a smaller bundle.)
The preference treatment is subtle, but it feels right to me. Clicking to switch modes visually does what you’d expect, switching from light mode to dark mode and vice versa. But that click, that explicit choice, is only saved to localStorage when it overrides the system default.
This retains the site’s ability to adapt fluidly when the system preference changes, instead of forcing an explicit click to forever shift the site in “manual” mode. It honors the immediate toggle choice, sticks permanently if it differs from the OS setting, and goes on matching the OS if the latest choice aligned with the OS preference.
All I did was remove the last localStorage.setItem() line from Kevin’s layout example:
My Vue theme toggle looked like this:
I ran into an initial flash problem that ended up being a result of how I was using named slots, but in the process found Josh Comeau’s meticuluous The Quest for the Perfect Dark Mode. It’s a wonderfully-thorough and illustrative exploration of the subject, complete with a dry sense of humor I adore.
Footnotes
Hilariously enough, it took vastly more time to prepare this article for code highlighting and including a filename ahead of a fenced code block. ↩