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-4] HWB normalization under-specified? #9228

Closed
svgeesus opened this issue Aug 23, 2023 · 7 comments
Closed

[css-color-4] HWB normalization under-specified? #9228

svgeesus opened this issue Aug 23, 2023 · 7 comments
Labels
css-color-4 Current Work

Comments

@svgeesus
Copy link
Contributor

As originally noted in another issue there is a lack of interop on the normalization of W and B values which sum to more than 100%.

The specification refers to normalization in passing, but does not explicitly define it, except by analogy (and also in the sample code):

The resulting color can be thought of conceptually as a mixture of paint in the chosen hue, white paint, and black paint, with the relative amounts of each determined by the percentages. If white+black is equal to 100% (after normalization), it defines an achromatic color, i.e. some shade of gray, without any hint of the chosen hue. In this case, the hue component is powerless.

The sample code, though, expresses this differently: if white + black is greater than or equal to 100% return a shade of gray (the value depending on the proportion of white to black) else use the values without normalization (because we know they sum to less than 100%.

I had thought the spec was clear but re-reading it, maybe it is not.

I'm interested to understand the different reading that resulted in the Firefox and Safari implementations, which do not follow the sample code.

@svgeesus svgeesus added the css-color-4 Current Work label Aug 23, 2023
@tabatkins
Copy link
Member

Hm, I suppose the "after normalization" doesn't actually reference anything, yeah. There should be a more explicit statement about normalizing the white and black %s to sum to 100% if they sum to >100%.

(I think I'd just assumed that was obvious from the text, but that's what I get for assuming.)

Chrome appears to also return rgb(96 96 96) right now from the hsl(90 calc(30% * 2) calc(70% * 2)) example. I have no idea how anyone is getting that. A 96 component is about 37%, and I just can't imagine what process is causing this number. (I also don't know how you got 77 from Chrome, tho.)

@svgeesus
Copy link
Contributor Author

I also don't know how you got 77 from Chrome, tho

int(0.3 * 255) = 77

@svgeesus
Copy link
Contributor Author

There should be a more explicit statement about normalizing the white and black %s to sum to 100% if they sum to >100%.

Yup (although the condition for returning a grayscale result is >= 100%)

(I think I'd just assumed that was obvious from the text, but that's what I get for assuming.)

Me too, I re-read and was like oh, whoops!

@tabatkins
Copy link
Member

tabatkins commented Aug 28, 2023

int(0.3 * 255) = 77

Right, that's certainly the value I'd expect. But I'm getting Chrome returning 96, so I don't know what you're doing that it's returning 77.

@svgeesus
Copy link
Contributor Author

This is the test

let test = document.createElement("div");
test.style.color = "hwb(90 calc(30%) 70%)";
console.log(test.style.color);
test.style.color = "hwb(90 calc(30% * 2) calc(70% * 2)";
console.log(test.style.color);

and in Chrome Canary Version 118.0.5977.0 (Official Build) canary (64-bit) I am getting 77 on both subtests, which is correct.

In what version of Chrome are you getting 96? Maybe an older version and a bug has since been fixed.

@tabatkins
Copy link
Member

Ah, I'm in 116, so yeah it might have been fixed since then, ok.

@svgeesus
Copy link
Contributor Author

svgeesus commented Sep 20, 2023

Hm, I suppose the "after normalization" doesn't actually reference anything, yeah. There should be a more explicit statement about normalizing the white and black %s to sum to 100% if they sum to >100%.

The term was removed but the statement is linkable. We now have

<p id="hwb-normalization">If the sum white+black is greater than or equal to <span class="css">100%</span>,
	it defines an achromatic color,
	i.e. a shade of gray;
	when converted to sRGB the R, G and B values are identical
	and have the value white / (white + black).</p>

This does still mean that out-of-sRGB-gamut colors do not round-trip through HWB because they are incorrectly seen as achromatic (live test). Consider this oog vivid magenta, color(rec2020 0.7 0.2 0.5):

// an oog, rec2020 color converted to sRGB
let tmp = (rgbToHsl(0.8892417662560173, -0.007998964113115263, 0.562048294772405));
console.log("hsl = ", tmp);
console.log("rgb from hsl = ", hslToRgb(tmp[0], tmp[1], tmp[2]));

let tmp2 = (rgbToHwb(0.8892417662560173, -0.007998964113115263, 0.562048294772405));
console.log("hwb = ", tmp2);
console.log("rgb from hwb = ", hwbToRgb(tmp[0], tmp[1], tmp[2]));

"hsl = " // [object Array] (3)
[321.87997894493725, 101.81538256963105, 44.0621401071451]

"rgb from hsl = " // [object Array] (3)
[0.8892417662560173, -0.007998964113115237, 0.5620482947724053]

"hwb = " // [object Array] (3)
[321.87997894493725, -0.7998964113115262, 11.075823374398276]

"rgb from hwb = " // [object Array] (3)
[0.6979511353179851, 0.6979511353179851, 0.6979511353179851]

Because -0.7998964113115262 + 11.075823374398276 >= 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-color-4 Current Work
Projects
None yet
Development

No branches or pull requests

2 participants