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-color-6] contrast-color() MVP in Level 5 #9166

Closed
LeaVerou opened this issue Aug 6, 2023 · 19 comments
Closed

[css-color-6] contrast-color() MVP in Level 5 #9166

LeaVerou opened this issue Aug 6, 2023 · 19 comments
Labels
a11y-tracker Group bringing to attention of a11y, or tracked by the a11y Group but not needing response. Closed Accepted by CSSWG Resolution css-color-5 Color modification css-color-6

Comments

@LeaVerou
Copy link
Member

LeaVerou commented Aug 6, 2023

In the NYC F2F in 2022, we discussed defining an MVP of contrast-color() that would only return black or white depending on what color text is most readable for the background color passed. This would address the most common use case where authors have a dynamic color (often user selected) and need to display text on it. Currently authors need to know a lot about a11y and color theory to calculate this reliably, and more often than not the result is suboptmal. You can see an example in this very page:
image

However, the only relevant resolution was this one:

RESOLVED: We have an unspecified default, the best available to the UA, which gets updated, only allowed when there aren't any candidates. If you include any candidates, algorithm is mandatory

But this only defines defaults, not a path for UAs to implement an MVP of this while we settle the details of the extended syntax. For this to happen, the simpler syntax needs to sit at an earlier level of CSS Color. UAs are extremely keen to ship an MVP for this and have been since 2022, so it's about time we settle on it, without being distracted by the multitude of issues for the extended color-contrast() syntax. Out of these issues, only these need to be resolved for this MVP, and none of them is really a roadblock:

Apart from those, we'd need to also decide on the syntax, which should be much simpler to do for this than for the extended case, since the point of this is to reduce the number of knobs authors have to understand and tweak and just do the right thing automagically, in line with the TAG principle on balancing simplicity and complxity.

I would propose just contrast-color(<color>) in Level 5 (since it's not CR yet) where:

  • Contrast algorithm is UA dependent (for background, this is the result with various existing algorithms, though UAs have also been doing their own explorations when they implemented accent-color). Yes, there is a concern that authors might be unhappy with the text color changing from white to black as UAs refine their algorithms, but remember this would only happen in case it improves the result. From conversations with Chrome folks, it appears they are happy to go this route (and have been taking a similar approach for other high level properties, e.g. text-wrap: pretty), hopefully other implementors share the same sentiment.
  • <color> is assumed to be background and the function returns white or black depending on which one produces the highest contrast for text (choosing white if there’s a tie). Yes, we have a resolution that it should be mandatory to specify whether the color argument is foreground or background, but in doesn't really make a difference here, so it would be unfortunate if authors had to add this noise everywhere.
  • If people are worried about syntax lock-in, we could even use an entirely different function name. E.g. max-contrast-color(<color>) or just max-contrast(<color>) since for every color, either white or black produce the maximum contrast. Or name it in a way that indicates it returns a foreground/text color.
@LeaVerou LeaVerou added Agenda+ a11y-tracker Group bringing to attention of a11y, or tracked by the a11y Group but not needing response. css-color-6 labels Aug 6, 2023
@svgeesus
Copy link
Contributor

svgeesus commented Aug 6, 2023

In the NYC F2F in 2022, we discussed defining an MVP of contrast-color() that would only return black or white depending on what color text is most readable for the background color passed. I thought we had a resolution on this, but I can’t find it.

The resolutions are in Minutes New York F2F 2022-08-02 Part II: CSS Color and Minutes New York F2F 2022-08-02 Part III: CSS Color .

I think the one you are thinking of might be

RESOLVED: We have an unspecified default, the best available to the
UA, which gets updated, only allowed when there aren't any
candidates. If you include any candidates, algorithm is
mandatory (Issue #7361: color-contrast() default
algorithm)

although (relevant to your proposal above) we also have

RESOLVED: Whatever keywords for foreground/background are named,
they are are required (Issue #7359)

@LeaVerou
Copy link
Member Author

LeaVerou commented Aug 6, 2023

Thanks @svgeesus, I updated the OP accordingly.

@stubbornella
Copy link

stubbornella commented Aug 6, 2023

I’m the PM for Web UI at Chrome, my team would be implementing color contrast if it were ready. I would like to get to resolution on this issue sooner than later because it is a high priority for us this year. This is my suggestion about how we could move forward. We don’t yet know the optimal algorithm for color contrast, and I believe we need to find a way to make this an iterative process, so we can start experimenting with it as soon as possible.

TL;DR I’m proposing that we specify an MVP contrast-color() function which has a UA controlled algorithm.

We want to support both user needs and author intent in a way that is performant, usable, accessible, readable, and beautiful. An example of where we've done this by initially specifying UA control is text-wrap: balance, where we started with only a couple heuristics, but plan to expand and refine over time.

Looking at this diagram, it is clear that there are a lot of cases where WCAG 2.1 can be improved on, however it may take time to find those opportunities and experiment to determine if they work.

PastedGraphic-1

If the author specifies the algorithm now, UAs won’t be able to make improvements and up-level the web. However, if we provide a basic color contrast function now, we can always allow more author control over the algorithm in the future. Going the other way around would require each site to manually upgrade, which would take a long time for users to realize the value.

An iterative, UA-first approach would also remove the burden to get everything right up front and instead move us to a more agile process. For example, we could try improvements behind a flag, effectively allowing us to see how that would affect UX across the web.

Yes, initially this would make the property a bit less predictable for the values in the middle of that chart, but the user benefit of being able to iterate in the UA outweighs author control (just for now). I am excited to see how much better we can make contrast-color() given time and iteration.

I propose that we:

  1. Specify an MVP contrast-color() function which has a UA controlled algorithm.
  2. Follow up on issues against that algorithm that can be considered independently.
  3. Begin UA experimentation on algorithm improvements
  4. After we’ve discovered the most important levers in contrast from our experiments, consider exposing them to authors on a case by case basis

@stubbornella
Copy link

To be clearer about what I'm proposing vs what @LeaVerou suggested:

I don't think we should specify white/black text or anything else about how the algorithm for contrast should work, except that it should always be better than WCAG 2.1 requires. It seems like the existing resolution may already be good enough to get started on that? (I'm not sure, I could definitely be reading it wrong? Especially the candidates part.)

RESOLVED: We have an unspecified default, the best available to the
UA
, which gets updated

Our goal is maximizing readability and that is a nuanced question as I can see from the many open issues on this. We will undoubtedly want to add more to the algorithm over time, and if we go with white/black, I don't see a path to reducing the contrast later, even if it still meets WCAG 2.1. If we leave it up to the UA (for now), we can experiment towards maximum readability and good contrast without an artificial constraint imposed by any particular existing algorithm, other than the floor, provided by WCAG 2.1.

@LeaVerou What syntax that would leave open the possibility of adding additional arguments to this function in the future? Perhaps a basic function that just takes in a color and returns another. Could we later add additional optional parameters to the function when we know more about where author control could be helpful?

I'd like to take all the ideas that have come through so far, and start experimenting with them in the UA, for the moment with the non-color expert author in mind. I realize that could feel like relinquishing a lot of control to the UA, but what I really mean is that I'd like for us to partner in a tight loop to improve the UA algorithm together. I think the v0 we would ship would look a lot like what @LeaVerou proposed. I'm suggesting we wait to put it into a spec until we feel confident that we've done everything we can in the UA to have good outcomes for users needing contrast, even when sites are built by authors who don't understand color.

@LeaVerou
Copy link
Member Author

LeaVerou commented Aug 22, 2023

To summarize for the call, what we need consensus on is:

  1. Do we generally agree to ship a very high level contrast-color() function focused around calculating a contrasting text color so we can address the most pressing use case while we figure out the specifics for addressing the more complex use cases?
  2. Assuming the resolution to (1) is "Yes", what exactly should be UA-dependent and what should be specified for this MVP?

For (2), the two proposals so far are:

  1. Algorithm is UA-dependent, return value is either black or white depending on which one produces the maximum contrast when used as text over the provided color (@LeaVerou, @fantasai)
    The rationale for this is:
    1. Given that existing contrast algorithms have so many issues, returning one of the two extremes makes it more likely to actually get a readable color
    2. Knowing what to expect (even if it's one of two values) makes authors more likely to use it than an "anything goes" function
    3. A pure value like black or white is more versatile: it can be blended with other colors, made lighter, darker, more transparent etc, to be used in other visual elements as well (e.g. borders and other decorations)
  2. Everything is UA-dependent, including the return value. The only guarantee is that the value returned will be a color that is guaranteed to be readable on the background provided. (@stubbornella)
    The rationale for this is
    1. It allows maximum UA innovation
    2. For the common use case of text colors, it can return a more aesthetically pleasing result than black or white out of the box
    3. It allows more innovation and experimentation around readability

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-color-6] `contrast-color()` MVP in Level 5, and agreed to the following:

  • RESOLVED: pursue this approach in level 5
The full IRC log of that discussion <emeyer> lea: contrast-color() is supposed to give an actual contrast
<fantasai> -> https://github.com//issues/9166#issuecomment-1688124086
<emeyer> …Because there are so many issues to figure out, in practice what happened was a year floated past and nothing really happened
<emeyer> …How about we ship a simple `contrast-color()` that take one color, the background, and returns either black or white, as fantasai proposed
<emeyer> …This sidesteps a number of things
<emeyer> …I think we need a number of levels to get at a full function
<TabAtkins> +1 to this scope reduction
<emeyer> …If we scope it down that far, we can get something out
<emeyer> …The only point of contention was, how predictable shoudl the return color be?
<chris> I strongly prefer the black-or-white MVP not the anything-goes one
<Rossen_> q?
<fantasai> +1 to lea's position
<emeyer> …Should only black and white be allowed, or can UAs have room to return other values?
<Rossen_> zakim, close queue
<Zakim> ok, Rossen_, the speaker queue is closed
<chris> +1 to lea's proposal
<bramus> present-
<emeyer> Rossen_: We’re over time, so, are there any objections to pursuing this in L5?
<florian> +1 to do it, preference for black/white only
<fantasai> https://github.com//issues/9166#issuecomment-1666863256
<fantasai> Let's do it
<emeyer> …(no)
<emeyer> RESOLVED: pursue this approach in level 5
<chrishtr> so is the resolution to allow not black and white, but prefer them?

@stubbornella
Copy link

stubbornella commented Aug 23, 2023

Everything is UA-dependent, including the return value.

The reason I wanted the text color to also be UA dependent is so we could maximize readability rather than contrast. I've seen everyone's thoughts in different threads which left me with the impression that readability is ripe for innovation and experimentation.

@LeaVerou
Copy link
Member Author

Everything is UA-dependent, including the return value.

The reason I wanted the text color to also be UA dependent is so we could maximize readability rather than contrast. I've everyone's thoughts in different threads which left me with the impression that readability is ripe for innovation and experimentation.

Thanks, I’ve added this point to the summary above.

@svgeesus
Copy link
Contributor

svgeesus commented Aug 29, 2023

I strongly believe that, following the science, the MVP should be restricted to achromatic colors (black or white, in the limiting case). Here is why:

Lightness and Chroma/Hue: effect on legibility and reading performance

Studies (Legge 1990) of both people with normal color vision, and people with low vision, have shown that sufficient luminance contrast is the primary factor affecting reading speed, and that adding chromatic contrast does not further increase reading speed. This is true for both those with low vision and those with normal vision:

We found no advantages of color contrast for low-vision reading. For text composed of 6° characters, all low-vision subjects read better with luminance contrast than with color contrast.

Beretta summarized the state of text readability research
(as of 2009) as follows:

  1. Luminance contrast is the dominant factor to address readability
  2. The luminance polarity affects readability (negative polarity is more difficult)
  3. The luminance of the background affects readability (lighter backgrounds are preferable)
  4. An additional color contrast does not facilitate reading when a sufficient luminance contrast exists
  5. On achromatic background, wavelengths at the extremes of the spectrum are more difficult for text.

Indeed, Zuffi et. al. (2009) found that for more muted color combinations, the presence of chromatic contrast (measured as Δab) impaired reading performance, compared to luminance contrast (measured as ΔL) alone:

By using regression analysis we verified that in the first case (“Low Chromatic” group) there is a
significant (p-value = 0.003) inverse relationship between reading performance and chromatic contrast; execution times increase as chromatic contrast increases, indicating a penalizing effect of this parameter. In the second case (“High Chromatic” group), on the contrary, the relationship is not significant, and this is consistent with the conclusions of other studies, which found that the chromatic contrast does not improve reading performance when a sufficient luminance contrast is present.

See their Figure 3

References

  • Giordano Beretta (2009) Text color polarity blog

  • G E Legge, G S Rubin (1986) Psychophysics of reading. IV. Wavelength effects in normal and low vision J Opt Soc Am A, 3(1): pp 40-51. abstract

  • Gordon E. Legge, David H. Parish, Andrew Luebker, and Lee H. Wurm (1990) Psychophysics of reading. XI. Comparing color contrast and luminance contrast. Journal of the Optical Society of America vol 7 issue 10 pp. 2002-2010 https://doi.org/10.1364/JOSAA.7.002002

  • Silvia Zuffi, Carla Brambilla, Giordano Beretta, Paolo Scala (2009)
    Understanding the readability of colored text by crowd-sourcing on the Web
    citation | fulltext PDF

@svgeesus
Copy link
Contributor

Regarding the transparency issue:

if the MVP is only returning opaque black or opaque white then there is no problem with text transparency. (Obviously it needs to be taken into account for the general case with a list of candidate colors, which can be partially transparent. But that case is also fairly simple, composite the text color onto the background color and use the result to do the contrast calculation).

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-color-6] `contrast-color()` MVP in Level 5.

The full IRC log of that discussion <emeyer> astearns: We discussed this last week but I’m wondering if we shoudl postpone
<emeyer> TabAtkins: Yes, we’d like to postpone to next week

@tabatkins
Copy link
Member

Me, @stubbornella, and a few of our color-related implementors discussed this yesterday.

The plan we'd like to get WG approval for is to, for now, pursue the simplest "output a color that contrasts with this input color" use-case. The other aspects the WG has discussed are important and we want to address them, but we believe we can make valuable incremental progress here without blocking ourselves in the future.

Exact proposal (loosely worded):


contrast-color(<color> max?)

Produces a "very light" or "very dark" color, which will contrast well with the input color. The precise algorithm for determining whether to output a light or dark color is UA-defined, as is the precise color produced. However, the output must be within X distance (delta-E units, presumably?) of white or black, and must be opaque. If max is specified, the output must be white or black. The output must make the same "very light" or "very dark" choice whether max is specified or not; that is, if it would produce black when max is specified, then it must produce a "very dark" color when it's not specified, etc.


This definition allows for some UA intervention and tweaking over time, producing near-black or near-white grays, or mixing in a little bit of the input hue, if the UA determines that would give the best result. By guaranteeing that the color is nearly black or white, we limit the potential for undesirable clashes (even if you mix in some hue, the maximum possible chroma is drastically limited), and limit the space of possible inputs that could produce a dramatically different result in different UAs, or the same UA over time. We believe this should be sufficient to avoid freezing on a particular algorithm and forcing future us to specify it.

If the author wants complete control over how they're tweaking their color, max gives them assurances of the output, so they can use color-adjust() or color-mix() to very slightly tweak the opacity or mix in a hue of their choice. Or they just get a guaranteed, clean black or white, if that's what they'd prefer.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-color-6] `contrast-color()` MVP in Level 5, and agreed to the following:

  • RESOLVED: function returns dark/light by default and the 'max' keyword for black/white
The full IRC log of that discussion <dael> lea: Last week we decided we do want to add to spec contract-color for most common use cae. Getting a suitable text color for arbitrary bg color. Question is should UA return only white/black and make their own algo. Or return color is up to UA and the UA returns something guar. to be readable
<florian> q+
<TabAtkins> i can represent Nicole/Chrome on this issue
<dael> lea: Argument from Nicole is that leaves more room to UAs for innovation. Sometimes max contrast is not as readable for everyone. Some people tend to prefer lower contrast
<dael> lea: Argument for black/white it's more predictable so authors can use more reliably. Also it guar. it's more likely to be readable. Also b/c it's either black or white authros can add shadow, etc. as an ingredient to do what they want
<dael> lea: More versatile, more predictable.
<TabAtkins> Q+
<TabAtkins> Yup I do
<dael> lea: We started expressing opinions last time but ran out of time. And TabAtkins requested an extra week to discuss in Google
<florian> q- later
<TabAtkins> *they
<dael> Rossen_: fantasai, anything you want to add?
<dael> fantasai: I'm pretty closely matched to lea
<Rossen_> ack TabAtkins
<dael> TabAtkins: We had a discussion. Me, Nicole, some of the canvas impl. New proposal which is essentially the preference from lea but with a bit of flexibility. You give an impot, get an output that's very light or very dark. Within some delta-e distance of white/black. Something that allows a little bit of play but still very close.
<dael> TabAtkins: Also with a keyword switch, prop 'max', that locks you into black or white so you can get predictable output
<dael> TabAtkins: I think this maintains the nice benefits of pure black/white but also allows some additional quality for browsers without distinct differences we were worried about
<dael> TabAtkins: I think this should still be okay. And can allow just black/white if impl want simple
<Rossen_> ack florian
<lea> q+ to say I like the new proposal, especially since authors can still get black/white with the max keyword
<dael> florian: I'm glad I let TabAtkins go first. Was in favor of just black/white. A little concerned if there's something smarter people will use it in interesting ways and someone will have to reverse engineer to match. But maybe if you limit the delta it won't happen too much
<lea> though it should be <color>
<lea> * though it should be <color> || max? I think
<Rossen_> ack lea
<Zakim> lea, you wanted to say I like the new proposal, especially since authors can still get black/white with the max keyword
<dael> florian: Perhaps reverse risk where some browsers aren't smart and people don't think to engineer for the slightly different. Not entirely sure it's worth it, but you seem to think it would be
<TabAtkins> not too stressed on the ordering, i think our previous grammars did put the <color> first to make things slightly more consistent/parseable
<TabAtkins> `<color> && max?`
<dael> lea: I like new proposal. authors can get balck/white with max keywork, but if they want something just looking nice they can get that. I think it should be possible to put values in either order.
<dael> Rossen_: [reads TabAtkins IRC]
<dael> Rossen_: Seems like new proposal from TabAtkins is winning solution here. Other opinions?
<lea> q?
<astearns> I am skeptical there are quality-of-implementation tweaks that will make this switch worth it (I expect you would need to know *what* the color will be used for to make effective tweaks). But I will not object.
<dael> TabAtkins: I propose lea and chris tell us the reasonable variation
<florian> s/people don't think to engineer for the slightly different/authors don't bother specifying max before applying effects, and then the browser(s) that were trying to be smart might need to revert to pure black and pure white, but then we're not worse off than where we started/
<lea> q+ one concern, from my designer days: It's much more common to want white text on a bright color, and a darker version of the background color instead of black. Right now you can either get black/white or dark/light, but not dark/white
<lea> q+
<dael> fantasai: Authors typically particular about hue and less about brightness. If you end up with navy blue text on white would author be happy? If Chrome gives navy blue but Safari gives dark maroon and FF does charcol gray, I feel like authors will be unhappy
<fantasai> s/white/cream/
<dael> TabAtkins: Our hope is distance from black and white is small enough that you can't have enough variation to clash on the page. And if they are unhappy you can say max.
<dael> fantasai: They may not be unhappy b/c looks good where they test
<dael> TabAtkins: Our hope is with the maximum divergence all results should be generally acceptable
<dael> fantasai: Let's say gray. People are sensitive to warm or cool. If some UA pick warm and some cool people will have sensitivity to what. What's benefit to allow gray be warmer or cooler? How far off can you be to get a benefit and no problem?
<dael> TabAtkins: Point is we want to experiment. We think this ability is valuable. There's a lot of work in experimentation and theory to figure out what's best. The hope is we eventually can write an algo. Hope is give authros something predictable for now that lets us play around to find the right spec
<Rossen_> q
<dael> fantasai: And you're arguing this should be default? We should create this difference in hue b/c that's a better default?
<lea> +q another issue is that if one browser returns black/white and another dark/light, this is practically unusable (without max)
<dael> TabAtkins: Yes. We believe the little bit of exporation will be acceptable as a default even if it's slightly different across browsers
<dael> lea: At first I quite liked proposal, but thinking more one issue is that if one browser gives always black/white and other does dark/light then the authors that want dark/light can't do anything with the values
<Rossen_> ack lea
<dael> lea: Even with relative color trying to think what math to use get light or dark on browsers that do black/white. I can do it with alwyas blakc/white
<dael> lea: Also, remember in graphic design more common to want white text on a bright color bg. If the color is so light it needs dark text it's more common to want not black. Current proposal doesn't let you distinguish and mix and max
<dael> TabAtkins: White is a valid light color
<dael> florian: But author can't ask for it
<dael> lea: What I'm saying is I want white if it would work and a dark color instead of black. Can't spec that intent i don't know if that's as wide spead as I remember. No way to spec that
<dael> TabAtkins: That can't be done in any syntax we discussed except listing explicit colors. Unless browser is smart enough to know
<dael> lea: If it returns white and black you can use max
<Rossen_> q?
<dael> florian: If as an author you want to manipulat eyou put in 'max'. If you want to tweak ask for the predictable thing
<dael> florian: I'm skeptable that the distance from white/black is small enough to be useful but not so large it can be bad
<lea> what I was referring to: lch(from var(--color) clamp(.2, l, 1) c h)
<astearns> +1 to florian's last point
<dael> TabAtkins: We're hoping it's not. Remember the falure case if we're wrong is we change the default to black/white
<fantasai> +1 to florian's point
<dael> Rossen_: I'd like to start getting to a resolution if we can
<Rossen_> ack fantasai
<florian> q+
<dael> fantasai: I have concerns about interop and suitability of automatic algo. I don't think it should be default, but I understand chrome has ideas to experiement. I don't think experiment is harmful if not shipping. I would prefer to spec black/white, add a note we're experiementing with other values, and let chrome experiment as a prototype
<lea> q?
<lea> q+
<dael> fantasai: If they get buy-in from dev community that they want the new behavior we can move. I don't think I'd want to spec UA magic at this point
<dael> TabAtkins: Issue with current channels is it's by definition people clued into the topic. if people are clued in they can do color manipulation on their own. We believe there is play to offer the general dev audience and there's not room in the channels we have for that
<Rossen_> ack florian
<dael> florian: One of the downside of fantasai's comment is Chrome wants a signal from authors that will mess with colors that they're going to do that. If we do the way fantasai suggested we don't have that signal. But you can maybe look for authors doing more with it
<dael> lea: I think what fantasai desc makes sense. Worried about interop when leaving to UA. If chrome experiments and gets results authors like we can add additional behavior for it.
<dael> lea: and/or we can introduce additional assurances to make sure result is predictable. Has to maintain same hue or something, but reduces innovation. I don't know what experiements they have in mind
<dael> TabAtkins: We don't know yet either. we'll play to see what gets good results
<Rossen_> q?
<Rossen_> ack lea
<dael> lea: Why not ship the simple version now, experiement, and add the new one later
<dael> TabAtkins: If it is something else it's by definition not going to be the first thing people reach for when they don't know what they want. The hop here is we can make the default good for people who just want a good text color. People who know color theory and want to play should be able to do that.
<Rossen_> q?
<dael> TabAtkins: The goal here precludes a switch for later. If this will be worthwhile it needs to be a default
<dael> Rossen_: And TabAtkins what you're saying is the additive behavior...what's the difficulty there? If we resolve on black/white now and add the 'max' keyword to do more?
<schenney> q+
<dael> TabAtkins: The 'mx' keyword forces you into black and white. All other values will be slightly-less contrastly. Also, it's that if you don't know how colors work, which most people don't, you're not going to reach for an optional keyword?
<dael> lea: Doesn't that depend on name?
<dael> TabAtkins: All optional keywords are treated as less default
<dael> fantasai: I see TabAtkins's point
<Rossen_> ack schenney
<dael> schenney: florian made an excellent point. If you wish to experiment having the default be to play and the max keyword it makes it rediculously easier to experiment. You get good signal. If you only have black/white it's very hard to infer what people want. For that reason the proposal from TabAtkins is best for a long term answer
<lea> TabAtkins: yes, optional keywords are used less often; but my point was that whether authors that don't know about color theory reach for the keyword depends on the keyword name. Like, the keyword doesn't need to be worded in such a way that it depends on color theory
<dael> florian: I'm not too hot for the proposal, but there is a chance it's useful and low risk if we define the distance short enough. If it's too far we'll get feedback and maybe we end on black/white
<TabAtkins> yeah we're thinking that, like, an #eee or an #eef rather than a pure #fff, very short distance
<dael> Rossen_: Let's see if we can resolve on TabAtkins's proposal. Other comments?
<dael> fantasai: It may be nice to start with mroe restricted audience trials to see if you get answers in those environments first.
<dael> Rossen_: how does that change the proposal?
<dael> fantasai: I think I would feel more postivie about it if there were positive signals in a restricted community
<dael> TabAtkins: We know for a fact that very often people reach for slightly off-white and off-black. That's from color design bible. Do #111 or #eee. That suggests we should be slightly off white/black for this. but it doesn't tell us exact value
<lea> q+
<dael> florian: Black and white are valid answers to if experiment isn't conclusive we can ship black/white
<Rossen_> ack *
<Rossen_> ack lea
<fantasai> those are both neutral grays...
<fantasai> but ok
<dael> lea: What TabAtkins is saying is true. It is common designers use off-white instead of white. Text size, font, weight, etc...the CSS function can't know it's context
<dael> TabAtkins: A lot of these factors could be inferred
<dael> lea: Are you suggesting we spec a color fucntion that's different based on what property it's in? That's not how color functions work
<dael> TabAtkins: I'm saying it could and we'll figure out to what extent we may want them to differ
<dael> Rossen_: We've talked for 30 minutes and I think we're starting to circle. We can try and resolve or go back to the issue to discuss more since this is a newer proposal.
<dael> TabAtkins: The exact proposal is new, but we have been discussing this area since NY F2F
<dael> lea: Agree. What about a straw poll
<dael> Rossen_: What are the options?
<dael> lea: 1. function returns black/white by default
<astearns> Returning a single non-b/w color based on the input color is one thing. Returning several different colors from one input color based on where the function is used is VERY different. You should make that explicit in the proposal if that is the case.
<dael> lea: 2. function returns dark/light be default and the 'max' keyword for black/white
<dael> s/be/by
<fantasai> 0, defer to jensimmons who unfortunately isn't here...
<TabAtkins> When the output space is wide, the difference matters more. When the output space is a small radius aroudn black/white, we believe it's probably fine.
<schenney> 2
<TabAtkins> 2
<florian> 2 (not a very strong opinion)
<iank_> 2
<astearns> 1
<lea> 1
<fantasai> Also! IIRC we'd resolved to require the "this is for text" vs "this is for background" keywords, is that being handled?
<smfr_> 2
<changseok> 1
<vmpstr> 2
<lea> fantasai: not for the MVP
<Rossen_> 2
<dholbert> abstain (no strong preference)
<emeyer> Abstain
<fantasai> lea, so which are we assuming? text or background?
<lea> fantasai: provided color is bg
<TabAtkins> input is background, output is text
<dael> Rossen_: We've got a clear signal for option 2
<dael> Rossen_: One of the things I didn't hear during discussion since this is a11y related- by returning black/white we are forcing more often higher contrast than user may prefer. Option 2 addresses this well.
<dael> Rossen_: Objections to function returns dark/light by default and the 'max' keyword for black/white
<dael> RESOLVED: function returns dark/light by default and the 'max' keyword for black/white
<dael> [agenda wrangling]
<dael> [waiting for Chris on #8543]

@svgeesus
Copy link
Contributor

svgeesus commented Sep 7, 2023

image

@tabatkins
Copy link
Member

So, in your estimation, which measure should we use for the thresholding, and what value feels reasonable for that threshold?

@LeaVerou
Copy link
Member Author

LeaVerou commented Sep 8, 2023

My takeaway from Chris' pad is that things are different for dark and light colors (and they also tend to be different when we're dealing with hues too), so it's hard to define a threshold that won't be too big for some and too small for others 😕

@svgeesus
Copy link
Contributor

svgeesus commented Sep 8, 2023

I don't have a conclusion at this stage, just wanted to get a feel for the color differences with the slightly-off whites and blacks you mentioned on the call.

@svgeesus
Copy link
Contributor

svgeesus commented Sep 8, 2023

If people want to play around with that example here it is.

@Myndex
Copy link
Member

Myndex commented Nov 4, 2023

Regarding slightly off white:

Yes, for main content, though there are issues worth discussing for both light and dark mode.

Light mode first

With a bright background, #ffffff can promote eye blistering fatigue, depending on how bright the display is relative to the eye's adaptation state. Considering that many modern devices easily exceed 1000 nits, visual fatigue is an ever-present problem.

One aspect of fatigue results from viewing high luminance relative to adaptation. If it is caused by a greater bleaching of cone opsins than can be replenished, aka the snow blind effect (this is not actual photokeratitis which is exposure to excess UV, but a loss in sensitivity due to high luminance), or from blue or HEV light, is a subject of continuing study.

There are some rather unfortunately misunderstandings floating around the internet suggesting that text be light grey, or that you don't want "too much contrast". Most of these ideas are bunk. One in particular seems to be sourced from an 2018 article at UXMovement, which is a source of much false or misleading information.

In light mode, text should ideally be black. Feelings of "too much contrast" are due to too much luminance. This problem led to the following:

The Paper Reading Experience

Something we've been working on, The Paper Reading Experience, is a design guideline for light mode, intended to emulate the nature of reading black ink on diffuse white paper, but presented on a self-illuminated display.

The problem with just using an off white like #eeeeee is that #eeeeee will simply become the peak adaptation level within a minute or two, and therefore no different than #ffffff.

Click for full size
Adaptation demo

So, to make an "off white" background useful, there needs to be a full white #ffffff in the peripheral vision in order to anchor the adaptation state to the peak white of the display.

The APC-Readability Criterion site uses this technique. (note this is a draft, and the responsive aspect of the site is a little buggy on cell phones.)

Background: 80% Edge: 100%
Paper Reading Experience

Earlier Experiments still up

Comments are welcome at Paper Reading Experience Discussion

Dark Mode

Unlike light mode, there is a level of "too much contrast" in dark mode because of the darker adaptation resulting in wider pupils, and the nature of glare, scatter particularly of point sources, and especially for those with astigmatism. Halation is more problematic in dark mode than in light mode.

We are evaluating a max contrast for dark mode, testing $L^c\ -90$ for text smaller than 24px, and $L^c\ -85$ for larger/bolder text. Thread to discuss maximum contrast.

How dark should the background be in dark mode? IMO that is relative to the surrounding environment. At night, in a dark environment, a full black BG could be fine, provided the text is also dimmer. For a #000000 BG, text is ideally between #cccccc and #e4e4e4.

A lighter dark mode BG such as #444444 and #f4f4f4 might be preferred by some for a lighter environment.

Examples:

DARK MODE light surround

DARK MODE dark surround

Summary

  • For SDR displays
    • In light mode, text is ideally full black #000, but the background is better as off white, 80%-85%, with peripheral elements at #fff to anchor adaptation.
    • In dark mode, text brightness needs to be relative to the background, and the background is ideally relative to the larger surround.
      • Currently testing $L^c\ -85$ to $L^c\ -90$ as maximums for dark mode text.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a11y-tracker Group bringing to attention of a11y, or tracked by the a11y Group but not needing response. Closed Accepted by CSSWG Resolution css-color-5 Color modification css-color-6
Projects
None yet
Development

No branches or pull requests

6 participants