Closed Bug 1878919 Opened 1 year ago Closed 11 months ago

Browser chrome CSS needs a way to detect that forced-colors was requested

Categories

(Core :: CSS Parsing and Computation, enhancement, P3)

enhancement

Tracking

()

RESOLVED FIXED
126 Branch
Tracking Status
firefox126 --- fixed

People

(Reporter: mstriemer, Assigned: emilio, NeedInfo)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

In bug 1791816's stack there are some changes to start using HCM colours in the browser chrome with the default theme. This is proving somewhat difficult as @media (forced-colors) does not apply to the browser chrome, so we have no way to detect it in CSS without relying on some combination of (prefers-contrast) and (-moz-platform).

It would be convenient to have a media query to detect if forced-colors was requested by the user, regardless of the platform. I think this should likely apply to Windows and Linux High Contrast themes, but not on macOS when the "Override the colors specified by the page with your selections above" setting is enabled (although I could be convinced otherwise).

@media (forced-colors: active) {
  :root {
    /* This would apply in-content but not the chrome on Windows/Linux HCM */
    --button-text-color: ButtonFace;
  }
}

The currently proposed solution is to provide another value for the forced-colors media query: requested. This would allow us to define HCM styles in the browser chrome while still allowing us to style with arbitrary colours when the user has a theme installed, for example.

So now we would have:

@media (forced-colors: active) { /* matches in-content with Windows/Linux HCM active */ }
@media (forced-colors: requested) { /* matches in-content AND the chrome with Windows/Linux HCM active */ }
@media (forced-colors) { /* matches in-content AND the chrome with Windows/Linux HCM active */ }
Flags: needinfo?(emilio)

This is to be able to let the browser chrome observe the in-content
forced-color values too.

Assignee: nobody → emilio
Status: NEW → ASSIGNED

So I believe there's a misconception as the default for Linux is also not forcing colors, right? So it won't apply there by default, either.

I believe making forced-colors: requested match in-content as well is wrong. The easiest and more sensible thing as implemented above is matching only if not active and requested, IMO.

That probably means that you want to use (forced-colors: active) and (forced-colors), but that seems sensible to me.

Flags: needinfo?(emilio)

Thinking a bit more about it... Is that really what you want for moz-button?

It seems what you want an answer for is basically "should the front end use system colors?" which, at least to be consistent with how we set up browser-custom-colors.css right now would be:

@media (-moz-platform: linux) or (prefers-contrast)

right? But I guess that would work for chrome but not for content (where you really just want (forced-colors)).

So I guess my question would be:

  • Is ^ right? In that case, does comment 1 help at all? Because I don't quite see how.
  • Isn't what you need basically an "is in chrome docshell" media query? That'd allow you to express what you want with something like:
@media (forced-colors) or ((-moz-is-chrome) and ((prefers-contrast) or (-moz-platform: linux)))

Which is arguably not pretty (and we could add a media query that just computed to that if needed, for convenience).

Sorry for the questions, I'm just trying to understand what you're trying to solve better.

Flags: needinfo?(mstriemer)

This is primarily aiming to override the brand/platform colours if the user is in forced-colors mode, but not if you're only in prefers-contrast. If you are in Windows HCM and have a LWT installed then the selector doesn't match (it's :root:not(:-moz-lwtheme)).

We don't want to be matching on (prefers-contrast), mostly for in-content stuff, but also in the browser chrome I think it would be fine/preferred for us to use our brand colours when applicable on macOS. They don't have any contrast issues so they don't need to change

The way the tokens are set up currently, tokens-platform.css is sort of our base tokens for the chrome. These define the old AccentColor and color-mix() on currentColor that applies to Linux and when the user has a LWT installed. The tokens-shared.css file is used both in the chrome and in-content and it has a media block to set the forced-colors values--these don't apply when a LWT is installed but they are the same in-chrome and in-content.

I haven't had a chance to try this build with my stack yet locally but I'll kick off some builds tonight so I can try it tomorrow. I think it is what we want still

Severity: -- → S3
Type: defect → enhancement
Priority: -- → P3
See Also: → 1878343

hey, just checking the status on this -- :dao did you have feedback?
ayeddi and I need it for our prefers-contrast/forced-colors project this half

Flags: needinfo?(dao+bmo)

Looks like this has changed how color-mix() is working with Windows HCM. Do you mind taking a look Emilio?

Flags: needinfo?(mstriemer) → needinfo?(emilio)

Blergh, I don't know how to code. Silly typo, it's fixed now.

Flags: needinfo?(emilio)

As per discussion in element, that's not quite what we want. Can you confirm when exactly do we want forced-colors to match in chrome pages?

Flags: needinfo?(mstriemer)

What Morgan said means, I think, that forced-colors should match in chrome iff you're on windows and using a high-contrast theme. That seems weird, but I guess ok if it makes the front-end easier to work with.

re: matrix discussion, my thoughts -
I think it might be helpful to distinguish, for posterity, @media forced-colors, forced colors mode (setting), and forcing colors (browser practise).

  • @media forced-colors allows developers customise how their web page behaves when a user has a forced colors mode active
  • forced colors mode is a setting (in both Firefox and Windows) that allows a user express a strong preference/need for a limited color palette
  • forcing colors is the practise of only allowing CSS system colors for rendering when a user has a forced colors mode active

Right now, we only force colors in content. Our chrome style sheets are allowed to use any colors they like, however when a forced colors mode is detected, they should use system colors to respect the user's preferences.

Because the issue described here is about customising UI when a forced colors mode is detected, I think it makes sense to add another value to @media forced-colors which lets browser developers customize chrome UI for forced colors modes. This value would be active only when an OS forced colors mode is enabled (Windows HCM), not when an in-content forced colors mode is enabled (Firefox HCM).

As emilio raised on matrix, we could accomplish the same outcome by using @media prefers-contrast and --moz-platform: windows, since the prefers-contrast query already works in chrome sheets. I think it makes more sense for frontend devs to keep system colors logic in forced-colors blocks, and put more general contrast-focused logic in prefers-contrast blocks. Forced colors modes are not necessarily used for contrast, despite the name conflation of "high contrast mode".

So, ok, after the discussion it seems like we want to distinguish the following cases:

  • Linux system theme (uses system colors, but not for contrast-enhancement or anything of the sort).
  • Windows+HCM system theme (must use system colors).
  • macOS with "prefers contrast". We want to keep the brand theme but mostly add outlines around buttons and tweak the color scheme a little bit, without going whole-sale into system colors.
  • Linux with "prefers contrast" (a "high contrast" theme). Should probably keep using system colors, but we might want to use extra outlines here and there or what not like on macOS.
  • In-content with prefers-contrast, but not forced-colors.
  • In-content with forced colors (including "firefox HCM").

Let me know if I've missed something here.

Options

1. Re-use forced-colors

Something like what comment 0 proposed (forced-colors: requested or what not), but not quite as described in comment 0.

This would make forced-colors match:

  • In content: As usual (no change).
  • In chrome: Only on Windows+HCM, regardless of the Firefox setting for pages.

Pros

  • Seems much simpler for the front-end (specially with the suggestion about forced-color-adjust: none below that makes our chrome and content consistent).

Cons

  • As Dão mentioned, this can be confusing, since we're not forcing colors in the chrome.
  • But maybe it is less confusing if we do the forced-color-adjust: none tweak for in-content suggested at the end of this comment? Then, forced-colors behaves consistently between content and chrome.

2. Boolean media query for this "must use system-colors" mode

A media query (name TBD) that would convey this "forced-colors-like" thing. In the past (before prefers-contrast was a thing) we used to have @media not (-moz-windows-default-theme). Maybe -moz-accessibility-theme or so, to match the UseAccessibilityTheme shenanigans?

Pros

  • Have much more leeway on how this behaves both in-content and chrome.

Cons

  • Have to name a new, non-obvious, non-standard media query.

3. Boolean query to distinguish chrome contexts

This another relatively simple version, which gives the front-end all the relevant power, and isn't that hard to name. Think of a @media (-moz-chrome-document).

Pros

  • Explicit: Gives the front-end all the power to make the decisions it wants. E.g., the "high-contrast" colors would be @media (forced-colors) or ((-moz-platform-windows) and (prefers-contrast) and (-moz-chrome-document)).
  • Not so hard to name.

Cons

  • Can get unwieldy.

4. More complex media query

I don't think we had discussed this, but I think it could be interesting to explore (I thought of this while writing the above sections).

One could imagine something like: @media (-moz-theme: platform | brand | high-contrast) which would allow us to distinguish the platform theme (Linux) vs. the high-contrast / forced-colors themes.

I think that basically allows us to distinguish the different color sets we want. This would match something like:

  • Chrome: platform on Linux, brand elsewhere, high-contrast on Windows+HCM.
  • Content: brand everywhere, high-contrast when currently forcing colors.

Pros

  • Have much more leeway on how this behaves both in-content and chrome.
  • Relatively easy to add more variants.
  • Not too complicated to teach, hopefully?
  • Doesn't tangle the forced-colors media query with our theming decisions on different platforms and contexts.

Cons

  • Still have to name and design a new, non-obvious, non-standard media query, instead of forced-colors.

5. Do nothing

Last only for completeness. Leave things as is, rely on the front-end including the right CSS files in the right contexts, and use the media queries in those contexts.

Pros

  • Nothing to do!

Cons

  • It's clear that this causes confusion and makes it hard for the front-end to organize the CSS as they really want. E.g. button-specific styles would need a chrome-only stylesheet of sorts.

Tangent: forced-colors in content

One thought that I proposed to avoid the extra difference between the chrome and the content styles could be to use forced-color-adjust: none unconditionally in our styles, even in content. That at least removes the difference between chrome and content, and I think makes me more comfortable with the forced-colors: requested solution.

I think my preference would be either:

  • (1) with the forced-color-adjust: none tweak below.
  • Explore (4) (probably with the same tweak)

Dao pointed out that we need to care about the HCM + lwtheme too, though my guess is that most of the solutions above would work, with or without special casing (we could either not match forced-colors in this case or fall back to the brand "theme" or so)

Pushed by ealvarez@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/3a9c0e656f69 Add a forced-colors: requested chrome-only media feature value. r=morgan,dao
Status: ASSIGNED → RESOLVED
Closed: 11 months ago
Resolution: --- → FIXED
Target Milestone: --- → 126 Branch
Blocks: 1894224
See Also: → 1916748
Regressions: 1919611
No longer regressions: 1919611
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: