-
Notifications
You must be signed in to change notification settings - Fork 689
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-5] add target contrast ratio to color-contrast? #4749
Comments
Oh and we would need to define what happens if none of the colors in the list meet the target contrast ratio One option would be to return whichever of white #FFF or black #000 gives the highest contrast ratio with the first parameter color. |
I really like the latter idea (to me it feels more natural than the former), although I really have no idea if there's a mathematical way to derive an acceptable color while minimizing changes to the perceived color (I do imagine there is, though). In my view, the whole point of a To me, it feels much more intuitive always selecting the best possible color from the list and then adjusting it with minimal impact to the perceived color to meet the given contrast ratio. |
What about if you want to pass a specific ratio (i.e. the result would be the color closest to that ratio) instead of just The closest value to the ratio would be selected (this would be the most likely case) If the ratio is identical between 2+ numbers, the result would be the first in the list. |
No, perhaps I explained it poorly. It selects the first one that meets the specified contrast ratio (or none, if none of them meet it). It doesn't select the one with the worst contrast. |
@una I believe that still runs contrary to the current function of @svgeesus I may have explained it poorly too, lol. The issue I have with it is say if multiple colors in the set have a greater ratio than the target, it will select the worst of the bunch. For example, if I have
Edit: Apologies, I misunderstood your second comment. This is definitely better than what I thought was how failing checks were handled, but this behavior might be unexpected. |
I like the proposal here, where the ratio provides a minimum contrast – and selects the first passing value in the list. If none pass that ratio, I see several options:
The idea of returning "closest ratio" is interesting. In some ways a nod to the idea that "contrast" is not always only about accessibility or text/background, but might be useful for other design goals – where you don't need to "pass" a particular value, but are more interested in creating a particular effect. Still, I think being able to order your preferences in a list, and select between min-or-max, would work pretty well to support those use-cases. |
@devmattrick I don't understand the implication that higher contrast is always "better". If that were the case, I would always want to select between Thinking about the highest-possible use-case, though - would there be value in a highly-simplified default where |
FWIW I created a Sass function called It uses the formula that WCAG 2.1 supplied in their guidelines, which is problematic for some color combinations. I am hoping that the newer I like the promise of the proposed |
@jhogue what you propose is useful, but as an addition to (rather than a replacement for) the current function.
You mean this discussion? |
Yes indeed. Very in-depth and interesting use case, but I was also referring to https://www.w3.org/TR/2020/WD-css-color-5-20200303/#relative-LCH specifically. It was the first I had heard of LCH to be used in CSS. |
Hi there -- new to this conversation. I have some thoughts on all of this. I would expect a For example, regarding this statement
LCh color model is not an end-all solution. There tends to be an assumption that different color models will automatically solve all of our human-perception-of-color issues, however it's simply not the case. There are continual advancements in color science in order to make models that are even more perceptually accurate (CAM02 and CAM16, developed in 2002 and 2016 respectively -- quite a bit more modern than LCh; a cylindrical adaptation of Lab which was defined in 1976). Even those don't solve all problems. There are also a lot of factors that go into selections of color, including how the color should adjust as it gets brighter or darker. There are aesthetic choices that can't be resolved by colorspace -- such as making a yellow color become more orangish as it gets darker. And to that effect, defining how much and at what rate the color gains/loses saturation. On top of that, default interpolation is linear, which does not always accurately reflect how designers would expect a color to change as it approaches black/white (darkest/lightest possible color value). For that, designers may hope to have finer control, such as a smoothing function to ensure the color interpolates along a curve. This problem is so complex I've made an (arguably just as complex) tool for designers and engineers to do exactly that-- generate colors based on a target contrast ratio (https://leonardocolor.io/). The engineering experience aims for the same thing it looks like being discussed here -- a single function call where you enter a color, a target ratio, and it spits out an appropriate color. However, because of the nuanced aesthetic choices that need to be controlled, this type of function also needs additional parameters: generateContrastColors({
// specific target colors provide control over how color changes:
colorKeys: ["FFFF00", "553300"],
// different color spaces may provide more desirable outputs:
colorspace: 'RGB',
// default interpolation is linear, however a smooth option may be better:
smooth: true,
// background color is needed as it takes 2 to calculate contrast:
base: '#ffffff',
// perhaps you want more than one color output from this scale:
ratios: [3, 4.5]
}); It would be fantastic if in the future there was a CSS color function that helped with all this, however it's important to not overlook the complexity of color, color selection, and adherence to aesthetics while manipulating a color to meet a target contrast ratio. All of that would come with the need for designer-facing tools to configure the parameters for engineers to use in the product. But until then, I think it is better suited to approach either of the simpler solutions above (simply calculate contrast, or return a color from a list of possible colors that matches the target) |
Hi @NateBaldwinDesign thanks for the helpful commentary and also the link to leonardocolor which we (the editors) have been playing with of late. In terms of what the proposed It's interesting that you mention the CIECAM color appearance models, and it is reasonable to ask why CSS Color 4 and 5 are defined in terms of colorimetry (Lab and LCH) instead of color appearance. The reason that color appearance (which was considered) could not be used in CSS is because of the inherent nature of CSS. Style rules from various origins (author, reader, user agent) are combined via specificity and cascading to yield an eventual result. Thus, all colors are specified at a very granular level on individual elements in the document tree. There is thus no notion of the overall visual field or surroundings in which colors will take on an appearance. Certain aspects of that (the background color or image for a specific element, the colors of nearby elements) could in theory be tractable to analysis by a CSS processor. Others (the colors of other windows that are visible in addition to the browser window) are not available (and must not be, for security and privacy reasons); the overall room luminance, the current white point and the degree of user adaptation to that white point are unknown to a CSS processor and thus cannot be used as input to a color appearance model. I had already noticed that your leonardocolor tool offers CIECAM02 as an option, but I was unable to find how to indicate any of the required parameters (such as adapting field luminance, chromatic induction factor, lightness contrast factor or the factor for the degree of adaptation) once it was selected. How do you account for these in your tool? Your point about better-than-linear interpolations and the need for easing or smoothing functions is well made. |
That's a fantastic looking tool Nate. I had the same question as svgeesus actually. As the CIECAM02 model appears to be built on D3 color, the answer is here: https://github.com/connorgr/d3-cam02
and here: https://github.com/connorgr/d3-cam02/blob/master/src/cam02.js#L105 |
Thank you for sharing the link Mike, that's correct. Quick caveat, sorry if this is not the appropriate location for this discussion CIECAM02 is a perceptual adaptation of CIELAB colorspace, and the d3-module allows us to leverage it as an optional color space for interpolation. Some of the interest in providing CAM02 has been inspired by the creation of Viridis, Magma, Inferno, and Plasma (from CRAN: https://cran.r-project.org/web/packages/viridis/vignettes/intro-to-viridis.html). These scales were created by drawing a bezier curve within a confined plane of CAM02 space in order to leverage its perceptual uniformity. There's a great walkthrough they give here: https://www.youtube.com/watch?list=PLYx7XA2nY5Gcpabmu61kKcToLz0FapmHu&v=xAoljeRJ3lU. When evaluating these scales and seeing the smooth transitions between hue and chroma, it makes sense (from a designers perspective) that these follow a smooth curve. However, in other color spaces (including Lab/LCh), a smooth curve does not produce a perceptually smooth transition. Albeit this is case-by-case, and certain cases are not as clearly different. For example, here's a comparison of a smooth (bezier) interpolation between three key (sample) colors (#FDE725, #218F8D, #440154). One is a smooth transition in LCh, the other is in CAM02. In this particular case, CAM02 provides a much smoother transition between colors. Mapping these interpolation paths also made it clear how irregular the interpolation path is in LCh. Why am I going on this tangent? Secondly, LCh will not solve all your problems. :-) Anyway, all this is to shed light on the problem I've already expressed, so I hope this is not too redundant or unnecessary. The utility expressed in the description of this issue seems to meet what I'd expect/hope for. Looking forward to seeing where this goes 👍 |
When I see people talk about the p {
color: color-contrast(
inherit(background-color)
vs
var(--brand-1), var(--brand-2), var(--brand-3),
white, black)
;
} I like that example, but it also demonstrates this issue perfectly. Despite a list of three brand colors there, obviously the preferred values, the current function will always select With browsers starting to implement |
happy to be of service 😅 I'd very much like to specify a target contrast. The "design goal" is usually to avoid usage of white/black; to stay within the tone of the brand color set instead and reserve usage of black and white to specific design cases. Generally, the "minimally viable/passing contrast color" is the one that design will want to use the most, and allowing us to specify which contrast target range we want, we can give up calculating/targeting these ratios on our own and let CSS "pick from the pool" we prepare as authors. I feel this is pretty critical to the convenience and power of this |
Summing up this thread, there seems to have been some confusion between two very different options
The first of these is the topic of the issue. It is a small adjustment to the existing The second is interesting, but is a totally new function and would need a concrete proposal. WCAG 2.1 contrast is also being radically changed in WCAG 3. There has also been some great discussion about the color modification aspect of the second option, parts of which could also influence further development of
As @LeaVerou just observed when we were discussing this issue, I wish there was a way to fork (parts of) an issue into a new issue). Getting back to option one though, @mirisuzanne I see your Agenda+ was this to suggest adopting the proposal? As there are no objections to it in this issue, I think we can just do it. |
@svgeesus yes, I just wanted to push us towards adopting the proposal. If we don't need a resolution for that, I'm happy with you making the change. |
What about |
If no color in the list meets the target, what do we get? We need to return something, so whichever of |
I like that. Saves people from having to specify them explicitly like @argyleink did. People still can specify them if they have a preferred one (e.g. white over black). |
Yeah, it's either that or "closest-color", and I agree black/white is the better default:
|
@mirisuzanne wrote
Currently, the color-contrast() function takes two arguments: a color, and a list of colors.
This requirement could be addressed by adding a third parameter, which is a target contrast ratio. Instead of comparing the whole list, comparisons stop once the target contrast ratio has been reached or exceeded.
This assumes that the list is in order of desirability, but the resolution of #4732 already implies this (if two colors in the list have the same contrast, the earlier in the list wins; this implies the stylesheet author put them in order of desirability).
The number is optional and if omitted, the whole list is searched to find the highest contrast ratio.
So for example
The text was updated successfully, but these errors were encountered: