Open annevk opened 1 week ago
I think this likely could be defined in terms of non-modifying relative color calculation. That is,
lab(51.2345% -13.6271 16.2401)
with colorspace srgb
selected, it gets serialized as if:
color(from lab(51.2345% -13.6271 16.2401) srgb r g b / alpha)
which would compute to a color(srgb 0.41587 0.503670 0.36664)
.
This would work just as well with the value #11223344
color(from #11223344 srgb r g b / alpha)
This is fully defined and already in engines, so should be straight forward to implement as well.
That's great! Any idea @svgeesus how to do the appropriate wording?
I'm thinking about it. It does need to be explicit in the spec, not just deducible to experts.
color(from lab(51.2345% -13.6271 16.2401) srgb r g b / alpha)
which would compute to a
color(srgb 0.41587 0.503670 0.36664)
.This would work just as well with the value
#11223344
Sure but we need to have language so that which of these two you get is clear, and can be interoperable.
So we already do color space conversion to either sRGB or Display P3. So we are guaranteed to have a CSS color in either of those color spaces. And Display P3 is always serialized as color(display-p3 ...)
. And sRGB is serialized as #rrggbb
with the HTML-compatible directive set.
So the main question is what happens when the HTML-compatible directive is not set (i.e., when the alpha
attribute is set). It seems nice to output color(srgb ...)
there, but this is not guaranteed as the CSS color, while it is guaranteed to be sRGB, can still have many different representations.
I see two ways of getting there:
color(srgb ...)
output similar to how we can force #rrggbb
output for sRGB colors.My current prototype does a combination of these. WebKit's internal Color
object has a way to force color(...)
serialization, which I use in the sRGB + alpha
attribute case.
This seems awfully generic given the need though.
While that's true in this case, there's a proposal for a JS Color API and as part of that we might (I've definitely wanted this before) want to choose the serialisation. For example hex with alpha has wider browser and tooling support so you might want to output the colour in that serialisation.
So the main question is what happens when the HTML-compatible directive is not set (i.e., when the
alpha
attribute is set).
You probably already know this and just simplified for brevity, but since you are prototyping an implementation I felt the need to point out that non-unity alpha is only one of the cases that means #rrggbb
is not used. The other is when this precondition is false::
The RGB component values are internally represented as integers between 0 and 255 inclusive (i.e. 8-bit unsigned integer)
Which means that extended-range sRGB will not use the hex serialization, either. For example color(srgb -0.41 0.92 -0.18)
is not representable with 8 bits per component due to the negative values.
True, but we only support "limited-srgb
" and "display-p3
" for now. If we add "srgb
" in the future it'll support the full sRGB range and for that we would also need a "use color()
function" override I suppose.
(I think adding "srgb" would be good. In general, now that we srgb is not clamped to [0,1], it's a pretty good default interchange value).
Would be good to clarify what behavior is desired for some edge case input values:
Should none
be serialized if it is explicitly stated?
<input type="color" colorspace="display-p3" value="color(srgb none 0 1)">
Should NaN / infinity be serialized.
<input type="color" colorspace="display-p3" value="color(srgb calc(NaN) 0 1)">
<input type="color" colorspace="display-p3" value="color(srgb calc(infinity) 0 1)">
Should currentColor be supported? And if so, what value should it serialize as?
<input type="color" colorspace="display-p3" value="color(from currentColor srgb r g b / 2)">
I agree that these cases should be explicitly covered, but also don't see a typical color picker generating them.
Right, the color picker is unlikely to ever generate them, but I believe the user can explicitly set the value as a string using the value attribute.
Yeah, I think those should be covered by how we invoke "parse a CSS <color>" without passing in context. So currentcolor
will always become opaque black for instance.
("limited-srgb
" unfortunately has to be the default to preserve compatibility with the existing control. We could add an opt-in for "srgb
". I decided to wait with adding a lot more until we've gotten some initial web developer feedback. It's easier to add things than to remove them again.)
I think I will address this problem in the HTML PR for now by adding language to the effect of
Set color to color converted to use the 'color()' function.
which will at least make it unambiguous what we need. I believe the questions Sam raised are already addressed by the combination of https://github.com/whatwg/html/pull/10456 and CSS Color, albeit not always in a straightforward manner:
currentcolor
will use the initial value of the color
property which is CanvasText
which becomes opaque black.I will leave this issue open to potentially allow for that (and other) wording to be improved if the CSS WG decides to add more primitives here.
Agreed about missing values (which includes NaN). CanvasText
is opaque black in light mode, opaque white in dark mode.
Per https://github.com/whatwg/html/issues/9940#issuecomment-1820495890 the color-scheme
property will always be in light mode when there's no context.
Oh right, the initial value.
For https://github.com/whatwg/html/pull/10456 we allow
<input type=color>
's internal color to be set as follows:value
attribute).This color is then color space converted depending on the
colorspace
attribute and serialized for API purposes and form submission. We only support the 'srgb' and 'display-p3' color spaces for now.When
colorspace
is set to "limited-srgb
" (default value) and thealpha
attribute is not set we specifically instruct CSS color serialization to use the hexadecimal syntax for compatibility.Otherwise we follow CSS color serialization directly.
However, what is not clear currently is what kind of normalization color space conversion applies. E.g., if the input is
lab(51.2345% -13.6271 16.2401)
, is the output going to becolor(srgb 0.41587 0.503670 0.36664)
? How is that defined? What if the input is#11223344
?Ideally from a web developer perspective I think it would always use
color(srgb ...)
orcolor(display-p3 ...)
unless we needed compatibility with the existing input as described above. But now I'm wondering if that is actually what we ended up requiring or if there are some other loose ends to tighten up.cc @svgeesus @lukewarlow @weinig