Let add-ons control website's CSS media queries or prefers-color-scheme.

NEW
Unassigned

Status

enhancement
P3
normal
4 months ago
Last month

People

(Reporter: c4609174, Unassigned)

Tracking

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [design-decision-needed])

Background

Firefox 67 introduced the new great prefers-color-scheme for websites. (see Bug 1494034)

Use case

As an add-on, I want to manipulate the light/dark state of web pages independently of the system state and per website, because:

  • users may want a dark system style, but light websites
  • users may want a light system style, but dark websites
  • users generally want more flexibility here
  • users use a system that actually does not support system styles (prefers-color-scheme), e.g. Windows 7, some (non-GNOME?) Linux distros, etc.

If you look on AMO, there are many "dark-style/theme" add-ons, currently applying their own custom CSS. If they, could, however detect that a website offers a "native dark" mode, they could choose that instead of their own custom overwrite.

Problem

After asking on Discourse on how to do that, I got a pretty hard workaround working (thx also to the tips from Stackexchange).

I've later answered my own question on Stackexchange and described the workaround there. Basically I extract the CSS manually and manually apply it. (JS needed, too, BTW…)

You can find it on AMO, if you want to try it out: https://addons.mozilla.org/de/firefox/addon/dark-mode-website-switcher/?src=external-bugzilla (or on GitHub)

Obviously, there are several problems with that approach:

  • As websites likely do not implement separate "prefers-color-scheme: light" it is nearly impossible to force a website to be light, when your system style is dark. Because you would need to have a generic way to "invert" a whole list of CSS or disable existing CSS somehow…
  • As already mentioned, this is a hard and cumbersome workaround to implement.
  • Overwriting the JS alone is very hard because for faking the return value of matchMedia you cannot create a new MediaQueryList. (new MediaQueryList() is not specified/possible.)
  • Even if you all overwrite the JS, you also need to care about the listeners that websites could actually attach to that… yet again, it get's complicated.
  • Also as for CSS media queries, if you only have (prefers-color-scheme: dark) this may be possible, but when websites concatenate multiple factors with and or so, we'll have another level of complexity.
  • After all, as this takes random CSS from websites and re-applies it, this may also easily break websites.

Solution

  • Way 1: Introduce some general way to manipulate media queries/CSS.
  • Way 2: Introduce some way to overwrite "prefers-color-scheme" globally and(/or better) per tab/website.
  • Also, some way to detect whether a website even offers such a mode would be nice. (Okay, you can look through the CSS again, but this is not-so-nice, as I've explained already.)

…for add-ons.

Another advantage this would have:

  • Maybe, we could thus also control all pages, i.e. internal Firefox pages like about:newtab or about:addons (see Bug 1519547), without "serious" (special/many) permissions, as we do not need access to the data directly.

That said, things like Bug 1529323 could eliminate most use cases, but I still think there are many flexible combinations or so that would make sense. (see my listed use cases above.)

Arrgh, now I still forgot the Stackoverflow link, so here it is: https://stackoverflow.com/a/55910185/5008962

Whiteboard: [design-decision-needed]
Component: Untriaged → CSS Parsing and Computation
Product: WebExtensions → Core
Component: CSS Parsing and Computation → Untriaged
Product: Core → WebExtensions

Setting this up as an enhancement for WebExtensions.

Status: UNCONFIRMED → NEW
Type: defect → enhancement
Component: Untriaged → General
Ever confirmed: true

In case I have not shared it already. Here is a direct link to my complicated workaround:

So IMHO that's way to complicated. Remember: all I do there is changing the result of one CSS media feature. And it's not perfect, it still misses a lot of features (I cannot really force a white page when system design is set to dark, actually, because websites likely default to their white design.) And it has a lot of bugs/edge cases of websites that may use arcane combinations of media queries (e.g. display and (prefers-color-scheme: dark) and (min-width: 240px) or so) I can hardly support in any way – without implementing a huge logic for evaluating media queries by myself.

Just my two cents:
Probably the most straight-forward way to expose this would be to add a new browserSetting for this. Maybe something like browserSettings.preferredDocumentColorScheme with possible values "light" and "dark". The default value, if not set by any other extension, being the OS's color setting.

I totally agree BTW. A quick API just to toggle this would be great.

So the Firefox 67 release is soon. So has a decision been done already?
It would be good to know if there is a plan to add such a feature or not.

This is not terribly hard to implement btw, we already have a browser preference for this (ui.systemUsesDarkTheme). It should be straight-forward to make it per-document too, if you stash a bit on the document:

https://searchfox.org/mozilla-central/rev/80a3d06820b31e1d95beb582f15e789cda9f6e03/layout/style/nsMediaFeatures.cpp#245

I think a decision needs to be made as to whether this bug is about controlling arbitrary media queries, or just prefers-color-scheme. The latter would be much easier to implement, but I don't really want to implement it as a separate feature if we're eventually going to wind up implementing the former anyway.

Yeah, thanks FYI. That said, it seems not to be visible/predefined in Firefox Nightly, as far as I see.

But yeah, I can set ui.systemUsesDarkTheme to 1 and hmm, it seems to work. (But it needs some doc.)


Generally, BTW, if you implement such a setting for switching ui.systemUsesDarkTheme also remember I, as an add-on maker, may also want to know whether the current page uses prefers-color-scheme, because if not, I may want to inject custom CSS for making it look dark.

I think a decision needs to be made as to whether this bug is about controlling arbitrary media queries, or just prefers-color-scheme.

So… when will a decision being made?

Should I possibly create a new issue for toggling ui.systemUsesDarkTheme via an add-on? IMHO, this seems like the easier way and if I would have to choose, I would choose this. (as said, easy and I don't know what use cases there are for modifying other media queries. Maybe only the other new ones for prefers-reduced-motion, i.e. these for accessibility. However, then there is the question why would you want to disable/toggle that?)

Another use case to consider:

  • As an add-on I may want to provide the ability to switch only the current tab/website to a dark or light theme.

(With media queries this would likely be possible.)

(In reply to rugk from comment #9)

I think a decision needs to be made as to whether this bug is about controlling arbitrary media queries, or just prefers-color-scheme.

So… when will a decision being made?

Should I possibly create a new issue for toggling ui.systemUsesDarkTheme via an add-on? IMHO, this seems like the easier way and if I would have to choose, I would choose this. (as said, easy and I don't know what use cases there are for modifying other media queries. Maybe only the other new ones for prefers-reduced-motion, i.e. these for accessibility. However, then there is the question why would you want to disable/toggle that?)

It's not that simple, as ui.systemUsesDarkTheme should change automatically to the correct option when the system Dark Mode setting is changed. What would happen if Dark Mode was toggled in the OS, should the Firefox option then be set to the real value or should it be locked completely from change by the OS? If so, how would that be communicated clearly to the user?

It seems wrong to me that ui.systemUsesDarkTheme should be able to lie about whether the systemUsesDarkTheme. IMO that value should always reflect the reality of the system settings. Adding another option, like Alexander Schlarb suggested, seems more proper.

Priority: -- → P3
You need to log in before you can comment on or make changes to this bug.