There is a quite new CSS media query feature called prefers-color-scheme
. It allows you to detect whether the system/user wants a dark website, so you can adjust your CSS.
Currently it is only supported by Safari and Firefox 67 or higher.
Anyway, it would be great, if you could make use of this. As you already have a dark mode, just (when the user did not override it) maybe automatically switch to the one the browser requests.
BTW: I also have a Firefox add-on called “Dark Mode Website Switcher” (source code) that you can use to toggle this setting in Firefox directly – without needing to change the system option. Maybe that could be helpful.
Enabling something manually is always cumbersome and if you have the possibility to automatically enable it, do so. And If I already have set this via a system setting, e.g., I really don't want to set it on each website again – it should just work!™
As for the feature itself, the use case should be clear.
Same Media Queries Level 5 CSS spec introduced these media queries: https://github.com/tootsuite/mastodon/issues/10975
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
need
prefers-color-scheme
is now well supported in desktop and mobile browsers. It's time to bump this up on the to-do list.
Mastodon default and Mastodon Light are two separate themes and need to remain available as separate themes for those who prefer one or the other through conventional means, so this is not a simple task. It's a cool idea but it doesn't have a lot of value-add over switching themes in settings.
IMHO you should just evaluate prefers-color-scheme
via JS once at initial user setup and then save that "setting" as the default one (implicitly) choosen by the user.
So that this just influences the user setting, so the themes can stay seperate. IMHO, that would be easiest.
_Or_ introduce a setting "automatic" in the user settings that does this at each access, i.e. evaluate the user setting and chose the "right" theme.
Similar to what @rugk is suggesting, I'd recommend solving it like so:
<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)">
<link rel="stylesheet" href="/light.css" media="(prefers-color-scheme: no-preference), (prefers-color-scheme: light)">
Clients will only process the appropriate CSS file based on the prefers choice. No javascript needed, and only a tiny bit of back-end logic for logged in users. I'm pretty sure that backend logic to include the style tag by theme choice is already in the code, so it just needs a couple extra lines and the addition of a "Default" or "Automatic" theme.
Ah great idea, also actually did not think/consider non-logged-in users.
This can be useful: https://github.com/postcss/postcss-dark-theme-class
@jamestomasino wrote:
_[..]_ I'd recommend solving it like so:
<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)"> <link rel="stylesheet" href="/light.css" media="(prefers-color-scheme: no-preference), (prefers-color-scheme: light)">
_[..]_
There is a subset of browsers that support the media=
filtering, but do not support the prefers-color-scheme
filter, thus both will not load [be applied].
You will need to add the following before the above lines:
<script>
if ( !window.matchMedia || (window.matchMedia("(prefers-color-scheme: dark)").media === "not all") )
document.head.insertAdjacentHTML( "beforeend",
"<link rel=\"stylesheet\" href=\"/light.css\">" );
</script>
See this article: prefers-color-scheme: Hello darkness, my old friend by @tomayac
There is a subset of browsers that support the media= filtering, but do not support the prefers-color-scheme filter, thus both will not load.
Both files will load, but with lowest priority (explanation) and none of them will be applied.
Complete script:
// If `prefers-color-scheme` is not supported, fall back to light mode.
// In this case, light.css will be downloaded with `highest` priority.
if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') {
document.documentElement.style.display = 'none';
document.head.insertAdjacentHTML(
'beforeend',
'<link rel="stylesheet" href="/light.css" onload="document.documentElement.style.display = \'\'">'
);
}
In practice, this only matters for IE11 and maybe KaiOS.
What about just adding the media query to the dark one and placing it below the light one? This seems to have worked for me on a few sites: Load a light theme, load a dark theme with the media query which overrules the light stuff.
This definitely works. It’s wasteful if you have a considerable amount of CSS. For Tootsuite most probably it’s negligible. 😃
Update: it might still be worthwhile to split, looking more closely at the CSS (which funny enough is in /app/javascript/...).
Most helpful comment
Similar to what @rugk is suggesting, I'd recommend solving it like so:
Clients will only process the appropriate CSS file based on the prefers choice. No javascript needed, and only a tiny bit of back-end logic for logged in users. I'm pretty sure that backend logic to include the style tag by theme choice is already in the code, so it just needs a couple extra lines and the addition of a "Default" or "Automatic" theme.