Whilst working on trying to implement this for Firefox I and @emilio noticed some ambiguity with the spec text.
The prefers-color-scheme media feature is used to detect if the user has requested the system use a light or dark color theme.
Does it really matter if this is a system or user agent preference? For example in non supporting operating systems Firefox could choose to pass light
and dark
when the user has enabled these themes and no-preference
when they haven't.
(prefers-color-scheme)
never appears to match, however shouldn't it match whenever the user has a preference? Especially given the boolean context statement.
We are at slight risk of sites never supporting no-prefererence given safari is only using light
/dark
and always returning true for no-preference
.
/cc @grorg @emilio
Also as a follow up, would it make sense for something like web driver to be able to control this setting? That way we could perhaps web platform tests for it?
cc @smfr, is WebKit's behavior intentional? If so, knowing the reasoning would be helpful to know what to implement.
Apple's implementation matches light
or dark
always when the system / app / view UI is running in light or dark mode — it is a binary choice on macOS — the user / app / view / system has no choice but to be in one of the two modes.
In Safari no-preference
is basically treated like a hypothetical prefers-color-scheme: any
— kind of like what you suggest for (prefers-color-scheme)
.
Given that (prefers-color-scheme)
does not read well or convey much intent, we decided to make it invalid. But again, we can change (prefers-color-scheme)
— and it would always be true
for us. Conversely no-preference
would always be false
for us.
I filed a bug for WebKit here with a fix: https://bugs.webkit.org/show_bug.cgi?id=191654
Typically we try to make the "empty" form have a falsey value for these prefers-
queries.
I agree that's a bit weird for this query, because it isn't clear if no preference is explicit or not. But the no-preference value is supposed to be false. @xeenon has already fixed the bug in WebKit.
As for the other points:
(prefers-color-scheme)
should match if the user has explicitly selected a scheme. I don't know why you'd want to author that though.I'll update the specification to clarify point 1. What are people's opinions on 2? Should no-preference mean "I don't care" or should it mean "only if i haven't chosen a scheme"?
Thanks @grorg, that all makes sense!
I (but note I'm not an expert in this area) personally think no-preference
should be exclusive to any of the other values matching (that is, you should never get into a state where (prefers-color-scheme: {light, dark})
and (prefers-color-scheme: no-preference)
apply at the same time. Also, it probably makes sense to require at least one of the values to match over all?
I think I'd be confused as an author if that was not the case, but again I'm not author nor an expert in this area, so my opinion probably doesn't have that much value :-)
I (but note I'm not an expert in this area) personally think no-preference should be exclusive to any of the other values matching (that is, you should never get into a state where (prefers-color-scheme: {light, dark}) and (prefers-color-scheme: no-preference) apply at the same time. Also, it probably makes sense to require at least one of the values to match over all?
That seems to be my understanding of how this should work also. I think it is fair that Safari for example might decide never to match for no-preference
as they are always light
or dark
.
2? Should no-preference mean "I don't care" or should it mean "only if i haven't chosen a scheme"?
As for Firefox, for the short term no-preference
might be used on platforms where we don't have an OS setting. Firefox likely will be using no-preference
for users who don't want to convey their preference also like Tor users.
My views are:
no-preference
should never match when light
or dark
does.(prefers-color-scheme)
should match if light
or dark
matches but not match when no-preference
matches.Here are my thoughts from designer's perspective. I know there is a gray area regarding definition of @media (prefers-color-scheme: no-preference)
and @media (prefers-color-scheme)
but let me explain the bigger picture with this example.
I the near future (I hope), there should be no distinction between light and dark theme, as there is no distinction between user's device screen size. We should only adapt the content and its visual properties to match user's device (whether it's a size or theme preference to something else) with media queries.
The thing is, you should only clearly define default design when there is no support for prefers-color-scheme
. In the end, this design is just one of the themes - light or dark. It only depends whether your default design should be light or dark. That's it :)
cc @lilles, I wonder if you have any thought here as the Blink implementor.
Having the keywords being mutually exclusive makes sense to me as well. IIRC, in Mojave you cannot have no-preference. If that's the case, authors will probably not end up having three different designs, but have either the light or the dark being the default, like:
@media (prefers-color-scheme: dark), (prefers-color-scheme: no-preference) {}
@media (prefers-color-scheme: light) {}
I have not checked with ChromeOS/Android if they will have a no-preference, but privacy/finger-printing was brought up as an issue on blink-dev (like mentioned above for Firefox as well).
As for now "light" and "dark" actually mean "as is" and "a specially crafted dark mode" respectively and I can't imagine what will "no-preference" mean in these terms. Maybe we should keep it binary?
I imagine this feature like this:
...you are presented with 4 cases you might want to cover:
@media (prefers-color-scheme: dark)
If your app has a dark-mode, use it.
@media (prefers-color-scheme: light)
If your app has a light-mode, use it.
@media (prefers-color-scheme: no-preference)
Use whatever mode you, as a developer/designer, thought of as the more suited for your app.
For an image galary app this might mean "dark".
For a text processing app this might mean "light".
Whatever you think of as the "better" mode for your app.
@media (prefers-color-scheme)
Simply means that the webbrowser at hand supports communicating it's users color-scheme preference.
If it doesn't, you will probably want to use the same as if "no-preference" were submitted.
However you might want to use this information to conditionally show/hide manual theme-selection buttons, when the same information can be provided via the users browser.
...I imagine there to be the following settings (maybe with per-domain overrides):
Forward the preferred color-scheme by the OS.
If the OS doesn't have a concept of color-schemes, set "no-preference".
No Preference
Let the website decide what is best.
Send "light" as your preference.
Send "dark" as your preference.
Remember, that you, as a developer, are always able to override the "prefers-color-scheme"-value.
For example, if the user explicitly selects a theme in your app.
This feature - at least in my eyes - is most useful to
a) get the fist time visitor directly into his favourite theme
b) have a website responding to the system color-scheme (which might depend on the time of day) and have it in sync with all other applications on the user's device
I think multiple UAs will soon ship this feature, so it would be good to have a decision on this.
CC @tabatkins
So concrete questions:
@media (supports-color-scheme)
evaluate to?(prefers-color-scheme)
== not (prefers-color-scheme: no-preference)
.(prefers-color-scheme)
.* Safari and @MatsPalmgren's patch to Firefox always evaluate `(prefers-color-scheme)`.
Though note that for Safari (prefers-colors-scheme) == not (prefers-color-scheme: no-preference)
also holds, since they don't have no-preference
.
WebKit matches light
when printing.
The CSS Working Group just discussed Clarification on prefers-color-scheme issues
, and agreed to the following:
RESOLVED: Close this issue no change, there is already language in the spec
The full IRC log of that discussion
<dael> Topic: Clarification on prefers-color-scheme issues
<dael> github: https://github.com/w3c/csswg-drafts/issues/3278
<Rossen> ah, misread the log...
<dael> emilio: Bascally, people are about to ship this MQ. There were unsolved issues. Should be straightforward
<dael> emilio: One is what should MQ evaluate in boolean context.
<dael> florian: It's defined in spec. If there's disagreement to what's defined I'm happy to hear it
<dael> emilio: Peoplediscussing on issue, but if spec says that's fine
<dael> florian: Same as no preference
<dael> dino: It makes using that form almost useless. You can't derrive meaning from it. If the query is prefers color scheme it will eval to true if they picked on
<dael> fantasai: Not prefers color scheme is interesting though. Makes it shorter to type out.
<dael> dino: You save 5 characters
<dael> TabAtkins: Prefers color scheme and not is clearly you either do or don't. It makes it this thing exists or doesn't and that's what null communicates
<AmeliaBR> @media not (prefers-color-scheme)
and @media (prefers-color-scheme: no-preference)
make sense as equivalents, to me.
<dael> emilio: Other question is if it should match light on print or if that's too smart
<dael> dino: That is another issue
<dael> astearns: I hadn't read the entire thread on #3278. Is that only what to do in boolean context?
<dael> emilio: Yeah
<dbaron> do existing implementations follow that answer?
<dael> astearns: Sounds like we have an answer. @media prefers-color-scheme is the same as null
<dael> astearns: It sounded like dino found it useless
<dbaron> (sorry, I can't unmute since the machine I'm dialed in on is semi-frozen thanks to yesterday's Windows update...)
<dael> dino: I don't know why you'd use it, but it does follow behavior so it's fine
<dael> TabAtkins: Yes, we're looking for consistency in how other MQs are handled
<dael> astearns: Prop: Close this issue no change, it is defined in spec. dbaron asked in IRC if impl match this
<dael> florian: I think we're light on tests
<dael> dino: We don' have any no-preference option
<dael> ??: I think blink is one that would have to change
<dael> emilio: Blink matches
<dael> dino: We should contribute tests for this. not sure how you can test user choice
<dael> florian: That's always the problem with testing MQs.
<dael> TabAtkins: Generally they're all manual tests. They're very hard
<dael> dino: Internally we have JS API only exposed in test system to set user preference for that page. Would be nice if al browsers could standardize on an API to do things like this. Would cover media style but nice if pointer events and touch events and that type of thing. Not for this WG I guess
<fantasai> sgtm
<dael> astearns: Sounds like there's consensus to close this issue and take what's in the spec currently. Objections?
<dael> RESOLVED: Close this issue no change, there is already language in the spec
I'll update the spec.
Thanks @grorg!
Hey, this sounds like a great idea! I'm forever clicking the "dark theme" button on websites, or finding a user style to provide one when the website doesn't support it.
As a user, I want to be able to choose whether I prefer a light or dark theme in my browser, rather than go hunting through my operating system's settings (which I've done, and I can't seem to find anything - I'm using Firefox with XFCE4 on Linux).
As the very least, I'd like a button that takes me to the right place in my desktop environment's settings.
That sounds like a feature request for your browser vendor.
I finally got around to clarifying the specification, particularly that the preference can come from the system or the user agent. We resolved that the boolean expression, while confusing and/or useless, should remain as is to be consistent with other queries.
In my testing, it seems Safari + Chrome + Firefox all agree on @media (prefers-color-scheme)
.
Most helpful comment
I imagine this feature like this:
As a web developer...
...you are presented with 4 cases you might want to cover:
If your app has a dark-mode, use it.
If your app has a light-mode, use it.
Use whatever mode you, as a developer/designer, thought of as the more suited for your app.
For an image galary app this might mean "dark".
For a text processing app this might mean "light".
Whatever you think of as the "better" mode for your app.
Simply means that the webbrowser at hand supports communicating it's users color-scheme preference.
If it doesn't, you will probably want to use the same as if "no-preference" were submitted.
However you might want to use this information to conditionally show/hide manual theme-selection buttons, when the same information can be provided via the users browser.
In a supporting webbrowser...
...I imagine there to be the following settings (maybe with per-domain overrides):
Forward the preferred color-scheme by the OS.
If the OS doesn't have a concept of color-schemes, set "no-preference".
Let the website decide what is best.
Send "light" as your preference.
Send "dark" as your preference.
Closing thoughts
Remember, that you, as a developer, are always able to override the "prefers-color-scheme"-value.
For example, if the user explicitly selects a theme in your app.
This feature - at least in my eyes - is most useful to
a) get the fist time visitor directly into his favourite theme
b) have a website responding to the system color-scheme (which might depend on the time of day) and have it in sync with all other applications on the user's device