Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-pseudo-4] Ensuring selection foreground/background contrast #6150

Open
chrishtr opened this issue Mar 26, 2021 · 10 comments
Open

[css-pseudo-4] Ensuring selection foreground/background contrast #6150

chrishtr opened this issue Mar 26, 2021 · 10 comments

Comments

@chrishtr
Copy link
Contributor

The ::selection pseudo-element allows the developer to change the foreground and background of a selection.

What happens if there is not good enough contrast between the selected colors? Webkit and Chromium (*) currently have code that inverts the background, if the background and foreground color are exactly
the same. Gecko does not have this logic. Here is an example page that differs.

Should we view this as a website bug, or an opportunity for the UA to intervene and ensure contrast? One argument for the latter could be that selection is primarily a UA feature, and therefore it's appropriate to intervene to override site bugs. But if we do so, any difference in heuristics between browsers could result in (probably accidentally) broken sites in some browsers.

Finally, the same question could be asked about the various other pseudo elements that are similar to selection.

(*) Webkit code link
Chromium code link
Gecko bug tracking an interop issue caused by this

@karlcow
Copy link
Member

karlcow commented Mar 29, 2021

Good comment from @jfkthame on https://bugzilla.mozilla.org/show_bug.cgi?id=1589539#c20

Tend to agree with Emilio, the first thing to do here (given that AFAIK we haven't been getting reports of this all over the place, it's this particular site that has CSS that just doesn't make sense unless they really WANTED the selection to be invisible) is to push for people to follow the spec. It's clear enough on this point, and it shouldn't be hard for authors to use it.

Defining special behavior for fillColor == backgroundColor for text selection gets messy; what about if the colors aren't exactly equal but differ by so little that it's not visible to the eye? We'd probably want to do this in terms of computing the contrast between them, not simple equality, and enforcing a minimum level of contrast. But then we'll end up with some author complaining that a subtle effect they're trying to achieve is impossible because the browser refuses to apply their colors as specified.

@fantasai fantasai added the css-pseudo-4 Current Work label Mar 30, 2021
@fantasai
Copy link
Collaborator

fantasai commented Mar 30, 2021

FWIW, I agree with @jfkthame that this should be considered a website bug.

A key point in that discussion though is that Blink/WebKit are not following the spec, and are applying an alpha value different from the one specified by the author; currently that's only allowed when the selection color paints over replaced elements’ content. So I think the key question here is whether Blink/WebKit intend to update to match the author’s specified color, or if ::selection should have a magic background-opacity setting.

(...which I suppose we could make non-magic if we actually added background-opacity as a property, but maybe that's a separate issue)

@chrishtr
Copy link
Contributor Author

So I think the key question here is whether Blink/WebKit intend to update to match the author’s specified color, or if ::selection should have a magic background-opacity setting.

I'd be ok with changing Blink behavior to match the spec if that's the consensus of the group. Deciding which way to go is the main reason I filed the issue.

I do think that it's bad for the browsers to have different heuristics than each other.

@astearns astearns added this to the APAC VF2F-2021-04-08 milestone Apr 2, 2021
@astearns astearns added this to Color Adjust in APAC April 8 2021 vFTF Meeting Apr 2, 2021
@fantasai fantasai moved this from Color Adjust to Highlight in APAC April 8 2021 vFTF Meeting Apr 8, 2021
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Ensuring selection foreground/background contrast.

The full IRC log of that discussion <Rossen_> Topic: Ensuring selection foreground/background contrast
<Rossen_> github: https://github.com//issues/6150
<TabAtkins> chrishtr: ::selection can set fg and bg color. What happens if they're not contrasty enough?
<TabAtkins> chrishtr: If they're the same, you can't read the text
<TabAtkins> chrishtr: For that reason, wk/chrome has special code to invert one of them in that case
<TabAtkins> chrishtr: There's at least one site reported as "can't see selections" in Gecko, because fg and bg were both white, and dev might not have noticed it in testing because wk/chrome intervene and fix it
<TabAtkins> chrishtr: so should we remove the intervention, or require it?
<chris> q+
<Rossen_> ack sanketj
<Rossen_> ack fantasai
<TabAtkins> fantasai: So someone was using white ::selection 'background' and 'color'. This works in wk/chrome because neither uses an opaque bg
<TabAtkins> fantasai: Gecko, following the spec, paints the color as specified
<TabAtkins> fantasai: So that brings up an interesting question of - we need to decide either the specified bg is what's used, or the bg is modified in some way
<TabAtkins> fantasai: If UA's differ, you'll get these interop issues
<TabAtkins> fantasai: They're either assuming the tranparency is there, or assuming it's not, and it might not work in the other cases
<TabAtkins> fantasai: So we need to have interop on the alpha of the bg color in ::selection
<chris> CSS Color 4 "The following system color pairings are expected to form legible background-foreground colors ... Highlight background with HighlightText foreground.
<TabAtkins> chrishtr: Our code is flipping the color, definitely - I checked
<chris> q?
<TabAtkins> chris: In Color 4, certain combos of system colors are required to be legible
<leaverou_> q?
<TabAtkins> chris: One of those pairings is HighlightColor and HighlightBackground
<leaverou_> q+
<fantasai> WebKit is using semi-transparent white, though, and that's probably what the author was expecting
<TabAtkins> TabAtkins: This is about author-chosen colors tho
<TabAtkins> chris: Ah, sorry
<myles> q+
<TabAtkins> leaverou_: I'm skeptical about UA intervening in author choices here...
<TabAtkins> leaverou_: Sounds like this issue happened because author was setting bg and not text?
<TabAtkins> fantasai: They were setting both
<Rossen_> q?
<Rossen_> ack chris
<Rossen_> ack leaverou_
<TabAtkins> leaverou_: Wonder if we could set better defaults? Set default bg to always contrast with text color using Color 5 colors
<fantasai> This is a case where the author explicitly asked for white text and white background
<fantasai> https://bugzilla.mozilla.org/show_bug.cgi?id=1589539#c5
<TabAtkins> myles: We think the spec should say *at least* that UAs should do something to make sure text is legible when highlighted
<TabAtkins> myles: No opinion on how far the spec shoudl go
<TabAtkins> myles: If the spec had an algo, that's fine
<TabAtkins> myles: If the spec just says "UA must do something", that's fine with us too
<TabAtkins> florian: Gets interesting when fg and bg are coming from different pseudos
<TabAtkins> florian: As an author you ought to set fg and bg together, but you can make this mistake
<TabAtkins> florian: So ahving a req that the UA must ensure the topmost fg and bg colors must contrast...
<TabAtkins> florian: Just making sure it's clear this can happen accidentally from different pseudos interacting, and that should be considered
<TabAtkins> fantasai: Cause of the bug:
<TabAtkins> fantasai: Person filing was assumign a semi-transparent whitewash with white text
<TabAtkins> fantasai: Chrome used to do that
<TabAtkins> fantasai: In Moz, it was rendering as solid white on white
<leaverou_> maybe we should adopt the previously proposed currentBackground keyword? Then UA default could be color: color-contrast(to 4.5 currentBackground vs white, black); (or appropriate system colors)
<fantasai> https://bugzilla.mozilla.org/show_bug.cgi?id=1589539#c5
<TabAtkins> fantasai: Author literally wrote ::selection { color: white; background: white; }
<TabAtkins> fantasai: They were expecting a particular rendering, which they were getting in Chrome and WebKit, but not Gecko, bc both were applying magic opacity
<TabAtkins> fantasai: So I think ti's harmful for some browsers to have magic opacity and osme not
<leaverou_> agreed with fantasai that if author specifies both, they should be respected
<TabAtkins> fantasai: So we need to align on some behavior here.
<TabAtkins> florian: I agree the state we're in is bad. Your proposal is one possibility. Myles's too - require all browsers to require legibility, but not specify how
<TabAtkins> florian: So if you're in a non-legible combo (for any reason, including the browser applying magic opacity or wahtever), the UA must change something to make it legible.
<TabAtkins> florian: Mandating one algo woul be great, but not sure we can do that.
<TabAtkins> fantasai: So example: authors choose a semi-transparent color for the bg. It's just enough to show a selection, but not enough to be probablematic against the bg
<TabAtkins> fantasai: In WK browsers, they'll compound the opacity, so it's even more faint of a bg. No legibility problem, but there's no longer a visible highlight, which is another problem.
<TabAtkins> fantasai: Now author has a problem despite making good choices originally.
<TabAtkins> fantasai: Whether we adjust or not is fine, but having it work differently across browsers is problem.
<TabAtkins> florian: So from Apple pov, if we specify a particular transparency, is that a problem for y'all?
<TabAtkins> smfr: Unsure if we have an answer to that. We want our selection to match the OS convention, so there's magical opacity
<TabAtkins> smfr: Dont' know if we'd be willing to turn off magic opacity in some cases, seems hard...
<TabAtkins> florian: If we specify exactly *your* opacity, woudl that work? Or do you reserve the right to change the exact method?
<TabAtkins> smfr: I don't think it's just opacity, there's a blend mode involved too
<TabAtkins> florian: So your behavior is too magic to spec?
<TabAtkins> smfr: Could probably spec it, but not all platforms might want to match the Mac OS conventions
<gregwhitworth> I agree with fantasai there
<TabAtkins> fantasai: Don't think people have problems with amtching OS conventions by defautl, just when the author says something specific, it should be predictable
<fantasai> s/predictable/predictable across platforms/
<TabAtkins> smfr: Generally we solve this by adding a CSS property that lets authors opt out of the correction
<TabAtkins> fantasai: We do have a long-standing request for a bg-opacity property
<TabAtkins> florian: So a default value of "auto" that can do magic things in some OSes?
<TabAtkins> fantasai: Maybe.
<Rossen_> q?
<TabAtkins> florian: I think we should explore more in this area.
<TabAtkins> florian: We *will* get interop problems if we don't ahve something like this.
<TabAtkins> Rossen_: So should we take this back to the issue?
<hober> q+
<hober> q- myles
<Rossen_> ack hober
<TabAtkins> hober: I think this action sounds reasonable.
<TabAtkins> hober: Could we resolve on the direction to go in - to require UAs to ensure there be sufficient contrast, exact details TBD?
<TabAtkins> hober: UAs do need to do something, right?
<TabAtkins> florian: I think elika pointed out that if you do that, you can hit the opposite situation, where a good fg/bg contrast gets magicked into a lack of contrast between selection and page bg?
<TabAtkins> hober: I think we can word the reoslution to avoid that
<TabAtkins> hober: I hope we can end up with simple details
<TabAtkins> hober: We just shouldn't punt on this, right?
<TabAtkins> fantasai: Yes, shouldn't punt. I just think I can throw a lot of wrenches into this. ^_^
<TabAtkins> fantasai: [another example]
<TabAtkins> fantasai: So there will be a lot of thought needed for the details
<TabAtkins> fantasai: And I think we should start be having an ability for authors to specify a more exact interop
<gregwhitworth> if you do it post composite you could but it would be a bad perf path but would ensure contrast so the text scenario would result in no adjustment by the UA
<TabAtkins> florian: I think we overall agree, just resolving to "browsers must do X" is a little premature at the moment
<fantasai> [another example] = author intended transparent selection background (so UA detection of no contrast between selection bg and page would be a problem) and is using color change on the text to indicate the selection
<TabAtkins> <br duration="15min">
@astearns astearns removed this from the APAC VF2F-2021-04-08 milestone Jul 24, 2021
@mrego
Copy link
Member

mrego commented Oct 5, 2021

We've been hit by this issue while working on improving ::selection in Chromium.

Chromium inverts the background color when the ::selection color and background color are the same, e.g. ::selection { color: lime; background: lime; } (check it live).

However WebKit does something different, because WebKit applies a 80% transparency to the web author specified background color, so it doesn't invert the colors in the previous example. But it inverts the colors in this example: ::selection { color: rgba(0, 255, 0, .8); background: lime; } (check it live).

This behavior comes from very old times (https://trac.webkit.org/changeset/1447/webkit), and there was even a comment in WebKit in the past stating that it was very unlikely that the background color gets inverted (https://trac.webkit.org/changeset/7766/webkit):

    // If the text color ends up being the same as the selection background, invert the selection
    // background.  This should basically never happen, since the selection has transparency.

Firefox never does this, for the colors specified by the web authors, it always respect them.
But when there are no user specified colors for ::selection, if the background of the element matches the default background for ::selection, then it inverts it. For example in Linux when you have a background: #3584e4; in an element, not in the ::selection pseudo, it'll invert the selection background color to make it visible (check it live).

So I guess browsers could have some freedom about what to do when the author doesn't specify any color (and try to match the platform conventions and all that). But I'm not totally convinced what they should do if the author specifies a color, shouldn't respect it? is it ok that WebKit adds a transparency to any color the author specifies?

We added a use counter in Chromium (included in version 93), very few pages are hitting it (~0.0003% so far): https://chromestatus.com/metrics/feature/timeline/popularity/3934

Anyway this is indeed an interop mess, and also this makes selection work differently than the new css-pseudos (particularly ::highlight()), dunno if that's something we want to keep or not. Or maybe we should do the same for other highlight pseudos, dunno.

It can also prevent the author to create some kind of potential pages/games that could use the same color to hide some text until the user click somewhere else and selection is gone and the text is visible (dunno really if this is a real use case, probably not with ::selection dunno when ::highlight() is available though).

CC @delan

@schenney-chromium
Copy link
Contributor

I would like to get this issue resolved. My proposal is that UAs should respect the colors given in ::selection pseudos (including inherited) as statements of an author's intent, even if that intent hides text when selected. UAs can do anything they want with selection painting in the absence of ::selection.

It seems desirable to add "only when both color and background color are given in ::selection" but it's not clear to me that it is implementable across browsers and is probably unnecessarily complex. I'm open to discussion.

Looking at the various proposals/concerns raised in the previous discussion:

  • This resolution ONLY applies when a ::selection pseudo is applied, in which case the have color and background color on the pseudo style inherited from some place that starts with good contrast, generally HighlightColor and HighlightBackground.
  • Allowing UA tweaks is very hard to spec in a way that handles all cases, including transparency, contrast thresholds, compatible color adjustment algorithms etc.
  • Allowing UA tweaks in the case of ::selection is essentially ignoring the authors intent, which was to style the selection. Unless we think that's a bad thing to allow (then why have ::selection?) I don't think we should try to second guess their design.

And as one data point, there is a WPT that explicitly tests for this behavior: css/css-pseudo/active-selection-018.html

@schenney-chromium schenney-chromium self-assigned this Nov 11, 2023
@astearns astearns added this to Unsorted regular in Feb 2024 Agenda Feb 8, 2024
@astearns astearns moved this from Unsorted regular to Wednesday morning in Feb 2024 Agenda Feb 8, 2024
@schenney-chromium
Copy link
Contributor

Adding Stack Overflow question:

@LeaVerou
Copy link
Member

Chromium inverts the background color when the ::selection color and background color are the same, e.g. ::selection { color: lime; background: lime; }

Note that inverting colors does not guarantee contrast. The closer you get to a mid gray, the lower the contrast, with gray having 0 contrast since it is the inverse of itself.


It seems like something that would really mitigate this problem is contrast-color(), which could be the default text color in the UA stylesheet, and could also be applied in cases like these.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-pseudo-4] Ensuring selection foreground/background contrast, and agreed to the following:

  • RESOLVED: Respect author colors in ::selection pseudo-elements, when given
The full IRC log of that discussion <emilio> schenney: both blink and WebKit modify the selection color so if fully opaque
<emilio> ... my last comment in the issue summarizes things
<emilio> ... if we try to standardize modifications to the colors you run into all sorts of challenges
<emilio> q+
<emilio> ... turns out there's a WPT that relies on this behavior in Gecko
<emilio> ... there's also people complaining about getting the right selection color in Chromium
<emilio> ... authors can get around it by setting a semi-transparent color
<florian> q+
<emilio> ... so proposal is that if a color is specified in a selection pseudo authors should respect that color
<kbabbitt> +1 to UAs not modifying author specified colors
<astearns> ack emilio
<emilio> ... regardless of whether they're good or bad
<TabAtkins> emilio: to be clear, that's only if they actually specify the colors
<TabAtkins> emilio: so for default selection, the UA is still able to - if the color is blue and they're on blue background, the UA cna ivnert
<TabAtkins> schenney: yes
<TabAtkins> emilio: so that's gecko's behavior, right?
<TabAtkins> schenney: yes
<lea> q+
<astearns> ack florian
<TabAtkins> emilio: then yes I agree, don't udnerstand why you'd mess with author colors
<emilio> florian: I completely agree, we're trying to put authors in charge of getting a good contrast and it should be predictable
<emilio> ... if everybody is trying to out-smart the authors in different ways then that's messy
<astearns> ack lea
<emilio> ... simplest way to match is just honor the author request
<emilio> lea: wanted to point out that (1) inverting color doesn't guarantee contrast
<emilio> ... specially as you get near grey
<emilio> ... contrast-color() seems a better approach
<emilio> fantasai: that's besides the point, the point is that if the author specifies the color, the UA should honor that
<emilio> ... they can do whatever they want in terms of the initial value
<emilio> schenney: I agree there's a need for contrast-color() would deal with that for authors
<emilio> astearns: seems like everyone agrees that UAs should respect colors in ::selection pseudos
<emilio> schenney: yeah you could say "when colors are given"
<emilio> RESOLVED: Respect author colors in ::selection pseudo-elements, when given
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 4, 2024
CSS Issue w3c/csswg-drafts#6150 was
resolved to require that browsers respect the author provided
colors in ::selection pseudos. Make the change.

Tested in unit tests and a WPT. Note that the default behavior
is not changed: chromium will still invert the color if the
text color matches the default selection highlight color.

Note the Mac layout theme was changed to return a non-transparent
color when the platform color is unavailable.

Bug: 4077125
Change-Id: I33fc8d18171da8b152f6e06a7f772b15f7175a16
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 4, 2024
CSS Issue w3c/csswg-drafts#6150 was
resolved to require that browsers respect the author provided
colors in ::selection pseudos. Make the change.

Tested in unit tests and a WPT. Note that the default behavior
is not changed: chromium will still invert the color if the
text color matches the default selection highlight color.

Note the Mac layout theme was changed to return a non-transparent
color when the platform color is unavailable.

Bug: 4077125
Change-Id: I33fc8d18171da8b152f6e06a7f772b15f7175a16
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5314122
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1268136}
aarongable pushed a commit to chromium/chromium that referenced this issue Mar 4, 2024
CSS Issue w3c/csswg-drafts#6150 was
resolved to require that browsers respect the author provided
colors in ::selection pseudos. Make the change.

Tested in unit tests and a WPT. Note that the default behavior
is not changed: chromium will still invert the color if the
text color matches the default selection highlight color.

Note the Mac layout theme was changed to return a non-transparent
color when the platform color is unavailable.

Bug: 40771258
Change-Id: I33fc8d18171da8b152f6e06a7f772b15f7175a16
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5314122
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1268136}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 5, 2024
CSS Issue w3c/csswg-drafts#6150 was
resolved to require that browsers respect the author provided
colors in ::selection pseudos. Make the change.

Tested in unit tests and a WPT. Note that the default behavior
is not changed: chromium will still invert the color if the
text color matches the default selection highlight color.

Note the Mac layout theme was changed to return a non-transparent
color when the platform color is unavailable.

Bug: 4077125
Change-Id: I33fc8d18171da8b152f6e06a7f772b15f7175a16
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5314122
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1268136}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Mar 14, 2024
… colors, a=testonly

Automatic update from web-platform-tests
Stop modifying author provided selection colors

CSS Issue w3c/csswg-drafts#6150 was
resolved to require that browsers respect the author provided
colors in ::selection pseudos. Make the change.

Tested in unit tests and a WPT. Note that the default behavior
is not changed: chromium will still invert the color if the
text color matches the default selection highlight color.

Note the Mac layout theme was changed to return a non-transparent
color when the platform color is unavailable.

Bug: 40771258
Change-Id: I33fc8d18171da8b152f6e06a7f772b15f7175a16
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5314122
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1268136}

--

wpt-commits: 08b559de93d13573b1c5b42d238e069eebebcc56
wpt-pr: 44917
jamienicol pushed a commit to jamienicol/gecko that referenced this issue Mar 17, 2024
… colors, a=testonly

Automatic update from web-platform-tests
Stop modifying author provided selection colors

CSS Issue w3c/csswg-drafts#6150 was
resolved to require that browsers respect the author provided
colors in ::selection pseudos. Make the change.

Tested in unit tests and a WPT. Note that the default behavior
is not changed: chromium will still invert the color if the
text color matches the default selection highlight color.

Note the Mac layout theme was changed to return a non-transparent
color when the platform color is unavailable.

Bug: 40771258
Change-Id: I33fc8d18171da8b152f6e06a7f772b15f7175a16
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5314122
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1268136}

--

wpt-commits: 08b559de93d13573b1c5b42d238e069eebebcc56
wpt-pr: 44917
@yisibl
Copy link
Contributor

yisibl commented May 9, 2024

To solve this problem once and for all, I hope browsers will implement contrast-color() as soon as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment