How to Provide Light and Dark Theme Color Variants in PWA



This content originally appeared on DEV Community and was authored by Federico Moretti

Light and dark themes have been around for a while, but there is still no way to configure them in PWAs. Or rather, there is no standard at the manifest level: I found a solution to overcome this limitation. It follows the conventions, even though we aren’t going to use the manifest.

Unfortunately, manifests are static JSON-formatted files which can’t change on user input. This means that they can only provide a theme_color key at a time: there’s no chance to make it dynamic. So, what if you want to support both light and dark themes? You have to choose between the two.

Ish. You can use a combination of CSS and JavaScript to let users set their own preferred theme, but you can’t change the theme_color accordingly—not from the manifest, at least. All is not lost! You can always choose not to choose, leaving the choice to the browser preferences.

Yes, because using CSS standards it’s possible to move the setting from the manifest to the HTML markup: this will load a different theme_color every time a user opens your PWA, directly taking the preferred value. You just have to put a couple of line in the head section of your pages.

<meta
  name="theme-color"
  content="#ffffff"
  media="(prefers-color-scheme: light)"
>
<meta
  name="theme-color"
  content="#1f2937"
  media="(prefers-color-scheme: dark)"
>

This is just a workaround, since the manifest and these settings are loaded only once: if you set a different theme via JavaScript, the preference will be kept as it was at the beginning. That’s why we still don’t have a definitive solution for switching PWAs from light to dark themes.

Not with regard to the browser’s color, at least. Of course you can change the web page colors, etc. on-the-fly without issues: but you will always have the same icons and the same theme_color specified on page loading. The key here is prefers-color-scheme which we can handle among other media.

In fact, I’m fixing my own theme switcher to change it on user choice as well. Currently, my solution supports system settings via prefers-color-scheme as a fallback if no preference has been specified from the website itself—I store it in the localStorage. But I need to modify it accordingly yet.

I’ll share my complete solution for theme switching once ready: you can already have a look at it on GitHub, but it lacks the prefers-color-scheme preference change, although I implemented the mechanism described above. There is considerable room for improvement.


This content originally appeared on DEV Community and was authored by Federico Moretti