You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-color-5] color-contrast() needs resolution logic if 2 or more have the same contrast #4732
Good catch, @argyleink I agree this needs to be specified
Given that the second parameter to color-contrast is a list of alternatives, then similar to other lists in CSS I suggest that the earliest match wins. In other words the logic is:
if the list has one item, it wins
if the list has two or more items, the first is the temporary winner but the next takes the winning place if it is better, and so on down the list
We also need to specify what happens if the first param is not a valid color, or any item of the second param are not valid colors.
thus, a later item with the same score as an earlier item will not win.
Note that these all give the same contrast of 6.08, when rounded to 3 significant figures as your tool does, @LeaVerou but when a higher precision is used, purple wins. I made that point in the spec text.
first wins, i dig it.
and nice catch on the higher precision contrast score! makes me wonder where the implementers will get their scoring algorithm from and whether or not we need to provide it (or one that works with CIE and offers higher precision) in the spec?
makes me wonder where the implementers will get their scoring algorithm from
The algorithm is given in WCAG 2.1 and the inputs are the relative luminances of the two colors being compared.
In utilities.js I have added that function, for convenience, although the inputs are sRGB only (same as WCAG):
function contrast(RGB1, RGB2) {
// return WCAG 2.1 contrast ratio
// https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
// for two sRGB values
// given as arrays of 0.0 to 1.0
var L1 = sRGB_to_luminance(RGB1);
var L2 = sRGB_to_luminance(RGB2);
if (L1 > L2) return (L1 + 0.05) / (L2 + 0.05);
return (L2 + 0.05) / (L1 + 0.05);
}
I also have a function sRGB_to_luminance(RGB) in utilities.js, primarily to help writing examples.
Notice that relative luminance is just the Y in CIE XYZ and conversions.js provides sample code to convert any of the predefined colorspaces to XYZ (for the rgb spaces, in two steps: undo gamma correction, then convert linear rgb to XYZ). The same goes for Lab to XYZ (two steps, convert to D50 XYZ then adapt to D65 XYZ) and LCH to XYZ (three steps, first convert LCH to Lab).
And even for calibrated spaces like CMYK etc, if a color profile is provided.
It is always just a case of computing two luminances, Y1 and Y2, then doing the simple ratio (with 5% flare compensation).
Luminance has been defined by an international standard since 1931, we don't need to define it in CSS just document how it is calculated, to help developers.
They're just assumed. If you write something into a property that takes <color> that doesn't match the grammar of anything defined under the <color> nonterminal, it's invalid and the appropriate error-handling happens automatically.
Activity
svgeesus commentedon Feb 3, 2020
Good catch, @argyleink I agree this needs to be specified
Given that the second parameter to
color-contrastis a list of alternatives, then similar to other lists in CSS I suggest that the earliest match wins. In other words the logic is:We also need to specify what happens if the first param is not a valid color, or any item of the second param are not valid colors.
svgeesus commentedon Feb 3, 2020
@una @LeaVerou should I go ahead and spec "first in list wins" or do you have other ideas on a resolution?
tabatkins commentedon Feb 3, 2020
Yeah, since there's no further context to decide ties, going with first-wins seems reasonable.
svgeesus commentedon Feb 4, 2020
Not so fast on the closing, Chris :)
svgeesus commentedon Feb 4, 2020
Note that these all give the same contrast of 6.08, when rounded to 3 significant figures as your tool does, @LeaVerou but when a higher precision is used, purple wins. I made that point in the spec text.
argyleink commentedon Feb 5, 2020
first wins, i dig it.
and nice catch on the higher precision contrast score! makes me wonder where the implementers will get their scoring algorithm from and whether or not we need to provide it (or one that works with CIE and offers higher precision) in the spec?
svgeesus commentedon Feb 5, 2020
The algorithm is given in WCAG 2.1 and the inputs are the relative luminances of the two colors being compared.
In utilities.js I have added that function, for convenience, although the inputs are sRGB only (same as WCAG):
I also have a
function sRGB_to_luminance(RGB)in utilities.js, primarily to help writing examples.Notice that relative luminance is just the
Yin CIE XYZ and conversions.js provides sample code to convert any of the predefined colorspaces to XYZ (for the rgb spaces, in two steps: undo gamma correction, then convert linear rgb to XYZ). The same goes for Lab to XYZ (two steps, convert to D50 XYZ then adapt to D65 XYZ) and LCH to XYZ (three steps, first convert LCH to Lab).And even for calibrated spaces like CMYK etc, if a color profile is provided.
It is always just a case of computing two luminances, Y1 and Y2, then doing the simple ratio (with 5% flare compensation).
Luminance has been defined by an international standard since 1931, we don't need to define it in CSS just document how it is calculated, to help developers.
svgeesus commentedon Feb 5, 2020
I should probably add another contrast example where the color list includes display-p3, prophoto-rgb, and lab and lch values.
argyleink commentedon Feb 10, 2020
feels like there's clear resolution on this issue, it's ready to close yeah?
svgeesus commentedon Feb 11, 2020
tabatkins commentedon Feb 13, 2020
Both of those cases are "doesn't match the grammar" and thus are invalid, right?
svgeesus commentedon Feb 14, 2020
Yes, I assumed so. Or, if a custom property is involved and the parser can't tell, invalid at computed value time.
Do we need t say either of those things explicitly or is it just assumed?
tabatkins commentedon Feb 20, 2020
They're just assumed. If you write something into a property that takes
<color>that doesn't match the grammar of anything defined under the<color>nonterminal, it's invalid and the appropriate error-handling happens automatically.svgeesus commentedon Mar 3, 2020
OK in that case this can indeed be closed.