Intent to Prototype: CIE LAB color functions for CSS

269 views
Skip to first unread message

Felipe Erias Morandeira

unread,
Mar 22, 2020, 12:46:15 PM3/22/20
to blink-dev

Contact emails

felip...@gmail.com


Specification

https://drafts.csswg.org/css-color-4/#specifying-lab-lch 


TAG review

https://github.com/w3ctag/design-reviews/issues/488 


Chromium bug


Summary

CSSWG has added the lch() and lab() functions to the CSS Color Module Level 4 specification. These are based on the CIE LAB color space, which is able to represent colors in a way that closely matches human perception. The purpose of this intent is to implement the functions lch() and lab() as described in the CSS spec.


Motivation

These new functions will enable design tools and design systems to handle colors with higher richness, fidelity, and flexibility, as well as improved accessibility. Supporting this functionality will also help unblock other color related additions to CSS.


Risks

Interoperability and Compatibility

There is interest on the part of Web developers and designers, although they might not take full advantage of this feature until it is eventually supported by more browsers and design tools.


Edge: No signals

Firefox: In development https://bugzilla.mozilla.org/show_bug.cgi?id=1352757 

Safari: In development https://bugs.webkit.org/show_bug.cgi?id=205675

Web / Framework developers:


Ergonomics

This feature will have no impact on the browser's ability to maintain good performance.


Activation

Developers could start using this feature right away but might be wary of doing so until other browsers implement it as well, so polyfills or preprocessor plugins might be useful.


Debuggability

The CSS editor in DevTools should support the use of the lab() and lch() functions to specify colors. I will contact https://groups.google.com/forum/?fromgroups#!forum/google-chrome-developer-tools to discuss this.


Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?

Yes.


Is this feature fully tested by web-platform-tests?

Yes.

Tests are lab-001 to lab-007 and lch-001 to lch-007 in:

 https://wpt.fyi/results/css/css-color?label=experimental&label=master&aligned

https://github.com/web-platform-tests/wpt/tree/master/css/css-color 


Link to entry on the Chrome Platform Status

https://chromestatus.com/feature/4592567062626304


Requesting approval to ship?

Not at this moment. I would like to have the opinion of more experienced contributors on whether it would make sense to implement-and-ship.



smaug

unread,
Mar 22, 2020, 12:52:15 PM3/22/20
to Felipe Erias Morandeira, blink-dev
On 3/22/20 6:46 PM, Felipe Erias Morandeira wrote:

>
> Firefox: In development https://bugzilla.mozilla.org/show_bug.cgi?id=1352757
A bug in a bug database doesn't mean "in development"





-Olli

L. David Baron

unread,
Mar 23, 2020, 12:27:14 AM3/23/20
to blin...@chromium.org, Felipe Erias Morandeira
On Sunday 2020-03-22 09:46 -0700, Felipe Erias Morandeira wrote:
> Summary
>
> CSSWG has added the lch() and lab() functions to the CSS Color Module Level
> 4 <https://drafts.csswg.org/css-color-4/#specifying-lab-lch> specification.
> These are based on the CIE LAB color space, which is able to represent
> colors in a way that closely matches human perception. The purpose of this
> intent is to implement the functions lch() and lab() as described in the
> CSS spec.

I'd like to call out that at least my understanding of these
functions is that they have a substantially larger color gamut than
sRGB, which means that they can't be accurately stored in sRGB-based
RGB values that only range from 0-255.

Their introduction also means that it's a lot easier to specify CSS
colors that are outside the device gamut, so questions of how to
clamp CSS colors to the device gamut become a much more important
interoperability question. Some basic options are those described
in the rendering-intent descriptor:
https://drafts.csswg.org/css-color-4/#descdef-color-profile-rendering-intent
I think the intent is that they *not* be clamped to the sRGB gamut
(when the device gamut extends beyond the sRGB gamut, which on
modern devices it generally does).

I also don't recall what the CSS working group decided about whether
lab() and lch() colors behave differently from rgb() ones for either
gradients or animations. I don't see anything about it in the spec,
but https://bugs.webkit.org/show_bug.cgi?id=205675#c2 suggests that
it's not completely the same.

I'm a bit skeptical of
https://bugs.chromium.org/p/chromium/issues/detail?id=1026287#c2
saying that they can all be converted eagerly to Chromium's existing
color infrastructure, but given that I'm not familiar with
Chromium's existing color infrastructure, and that I don't remember
how a bunch of the spec issues were resolved, I can't be sure.
As smaug pointed out, there's no evidence in that bug that anything
is in development.

That said, I'm personally comfortable with the feature, although my
understanding is that it requires a larger amount of work (at least
in Firefox) than the Chromium bug comments suggest.

-David

--
𝄞 L. David Baron https://dbaron.org/ 𝄂
𝄢 Mozilla https://www.mozilla.org/ 𝄂
Before I built a wall I'd ask to know
What I was walling in or walling out,
And to whom I was like to give offense.
- Robert Frost, Mending Wall (1914)

Manuel Rego Casasnovas

unread,
Mar 23, 2020, 1:39:14 AM3/23/20
to blin...@chromium.org

On 22/03/2020 17:46, Felipe Erias Morandeira wrote:
> Requesting approval to ship?
>
> Not at this moment. I would like to have the opinion of more experienced
> contributors on whether it would make sense to implement-and-ship.

IMHO, you should implement this behind a runtime flag (specially now
that the Chromium schedule is on hold) and once everything is ready send
an intent-to-ship to turn the flag on by default.

Bye,
Rego

Felipe Erias Morandeira

unread,
Mar 23, 2020, 2:53:32 AM3/23/20
to blink-dev
On Monday, 23 March 2020 14:39:14 UTC+9, Manuel Rego wrote:

IMHO, you should implement this behind a runtime flag (specially now
that the Chromium schedule is on hold) and once everything is ready send
an intent-to-ship to turn the flag on by default.

Thank you, that is reasonable. I'll do that. 

Best,
Felipe

Felipe Erias Morandeira

unread,
Mar 23, 2020, 2:53:52 AM3/23/20
to blink-dev, felip...@gmail.com, sm...@welho.com
You are right, apologies for the confusion. I wasn't sure which option to pick from the ones that chromestatus.com provided.

Best,
Felipe

Felipe Erias Morandeira

unread,
Mar 23, 2020, 4:02:44 AM3/23/20
to blink-dev, felip...@gmail.com
That is very informative, thank you very much.

As you say, a complete implementation of this feature might end up requiring a substantial amount of work. My plan is to go step by step, beginning with a reduced scope that makes use of Chromium's existing color infrastructure, and building from there.

As I go along, I expect to get a better understanding of whether/how things need to evolve further, both on Chromium and on the spec.

Best regards,
Felipe

Mathias Bynens

unread,
Mar 23, 2020, 4:12:58 AM3/23/20
to Felipe Erias Morandeira, Changhao Han, blink-dev
On Sun, Mar 22, 2020 at 5:46 PM Felipe Erias Morandeira <felip...@gmail.com> wrote:

Debuggability

The CSS editor in DevTools should support the use of the lab() and lch() functions to specify colors. I will contact https://groups.google.com/forum/?fromgroups#!forum/google-chrome-developer-tools to discuss this.


You could email devtoo...@chromium.org instead, per the guidelines. Feel free to CC me and +Changhao Han, we'd be happy to help!

Anders Hartvoll Ruud

unread,
Mar 23, 2020, 5:18:53 AM3/23/20
to Felipe Erias Morandeira, blink-dev
On Sun, Mar 22, 2020 at 5:46 PM Felipe Erias Morandeira <felip...@gmail.com> wrote:
I had a look at the tests. They are basically all the same test with different parameters. To qualify as "fully tested" we should have tests for (off the top of my head):
  • Basic painting (which is what we already have)
  • css-om, for both specified and computed styles
  • css-typed-om, for both specified and computed styles
  • Transitions, animations
  • Gradients
  • Passing and using the color in a paint worklet
  • CSS.registerProperty with "<color>" syntax

Link to entry on the Chrome Platform Status

https://chromestatus.com/feature/4592567062626304


Requesting approval to ship?

Not at this moment. I would like to have the opinion of more experienced contributors on whether it would make sense to implement-and-ship.



--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/41b32b56-2da2-421d-987a-3b28fbc16eb1%40chromium.org.

Felipe Erias Morandeira

unread,
Mar 23, 2020, 10:27:45 AM3/23/20
to blink-dev, felip...@gmail.com, chang...@google.com
Thank you very much, I will do that.

Best regards,
Felipe 

Felipe Erias Morandeira

unread,
Mar 23, 2020, 10:50:27 AM3/23/20
to blink-dev, felip...@gmail.com


On Monday, 23 March 2020 18:18:53 UTC+9, Anders Hartvoll Ruud wrote:
I had a look at the tests. They are basically all the same test with different parameters. To qualify as "fully tested" we should have tests for (off the top of my head):
  • Basic painting (which is what we already have)
  • css-om, for both specified and computed styles
  • css-typed-om, for both specified and computed styles
  • Transitions, animations
  • Gradients
  • Passing and using the color in a paint worklet
  • CSS.registerProperty with "<color>" syntax

Thank you, good point. There is already a comment in the Chromium bug about creating more tests and resolving ambiguities in the spec, I will follow up on that.

Some of those items might require a bit of spec work in order to agree what the desired output would be. Gradients, for example, could be a good use case for this feature (e.g. you could define two color-stops of the same luminosity and expect a gradient where that luminosity is preserved throughout) but this is not part of the spec at the moment.

Best regards,
Felipe

Jeffrey Yasskin

unread,
Mar 23, 2020, 12:28:55 PM3/23/20
to smaug, Felipe Erias Morandeira, blink-dev
I've tried to fix this chromestatus entry and filed https://github.com/GoogleChrome/chromium-dashboard/issues/793 to try to help people do better in the future.

Jeffrey

ch...@w3.org

unread,
Mar 24, 2020, 2:43:44 PM3/24/20
to blink-dev, felip...@gmail.com


On Monday, 23 March 2020 10:50:27 UTC-4, Felipe Erias Morandeira wrote:


On Monday, 23 March 2020 18:18:53 UTC+9, Anders Hartvoll Ruud wrote:
I had a look at the tests. They are basically all the same test with different parameters. To qualify as "fully tested" we should have tests for (off the top of my head):
  • Basic painting (which is what we already have)
  • css-om, for both specified and computed styles
CSSWG recently agreed to move the serialization of color from CSSOM to the CSS Color spec.  Making those edits is on me. There has been active discussion on how to serialize. So I agree this needs to be tested, but it also needs to be fully specced too.
  • css-typed-om, for both specified and computed styles
Agreed.
  • Transitions, animations
Yes
  • Gradients
Yes, and that also depends on recent discussions of Working Colorspace. I plan to add an example to the spec soon, showing how different color models can be used in gradients.
  • Passing and using the color in a paint worklet
Could you explain more about tht one, what exactly you would like to see tested?
  • CSS.registerProperty with "<color>" syntax
Oh, nice. I suspect the spec is not up to date there.

Some of those items might require a bit of spec work in order to agree what the desired output would be.
Yes.
Gradients, for example, could be a good use case for this feature (e.g. you could define two color-stops of the same luminosity and expect a gradient where that luminosity is preserved throughout)
I suspect you mean Lightness, not luminosity. But yes, that would be a good example.

but this is not part of the spec at the moment.

Right, the working colorspace section needs to be worked on first, then things like gradients, compositing, animations and transitions will follow from that.
 

Anders Hartvoll Ruud

unread,
Mar 25, 2020, 4:31:12 AM3/25/20
to ch...@w3.org, blink-dev, Felipe Erias Morandeira
On Tue, Mar 24, 2020 at 7:43 PM <ch...@w3.org> wrote:


On Monday, 23 March 2020 10:50:27 UTC-4, Felipe Erias Morandeira wrote:


On Monday, 23 March 2020 18:18:53 UTC+9, Anders Hartvoll Ruud wrote:
I had a look at the tests. They are basically all the same test with different parameters. To qualify as "fully tested" we should have tests for (off the top of my head):
  • Basic painting (which is what we already have)
  • css-om, for both specified and computed styles
CSSWG recently agreed to move the serialization of color from CSSOM to the CSS Color spec.  Making those edits is on me. There has been active discussion on how to serialize. So I agree this needs to be tested, but it also needs to be fully specced too.
  • css-typed-om, for both specified and computed styles
Agreed.
  • Transitions, animations
Yes
  • Gradients
Yes, and that also depends on recent discussions of Working Colorspace. I plan to add an example to the spec soon, showing how different color models can be used in gradients.
  • Passing and using the color in a paint worklet
Could you explain more about tht one, what exactly you would like to see tested?

Nothing fancy: e.g. set color:lab(...) on some element, use the 'color' property as an input to a paint worklet, then paint a rectangle with that color, and compare it to a ref which does the same painting with a normal canvas. Or something.

In Chrome, paint worklets are (/can be) a bit special, since they can run off-thread. Special care is required to pass a css value across a thread boundary, so a test like that is worth it to verify that the "special care" is maintained for lab() colors too.
  • CSS.registerProperty with "<color>" syntax
Oh, nice. I suspect the spec is not up to date there.

Some of those items might require a bit of spec work in order to agree what the desired output would be.
Yes.
Gradients, for example, could be a good use case for this feature (e.g. you could define two color-stops of the same luminosity and expect a gradient where that luminosity is preserved throughout)
I suspect you mean Lightness, not luminosity. But yes, that would be a good example.

but this is not part of the spec at the moment.

Right, the working colorspace section needs to be worked on first, then things like gradients, compositing, animations and transitions will follow from that.

Can you confirm that dbaron is correct about lab colors not being (accurately) representable in RGB with 0-255 per component, and that we can't simply convert to RGB before painting? We are trying to figure out if our 0-255 per component blink::Color is enough, or if we'd need to change it.

If lab() can't be accurately represented in RGB, would there be any value in shipping lab() support which converted to RGB lossily for painting?

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Anne van Kesteren

unread,
Mar 25, 2020, 4:54:37 AM3/25/20
to Anders Hartvoll Ruud, Chris Lilley, blink-dev, Felipe Erias Morandeira
On Wed, Mar 25, 2020 at 9:31 AM Anders Hartvoll Ruud
<and...@chromium.org> wrote:
> Can you confirm that dbaron is correct about lab colors not being (accurately) representable in RGB with 0-255 per component, and that we can't simply convert to RGB before painting? We are trying to figure out if our 0-255 per component blink::Color is enough, or if we'd need to change it.

Is conversion to 0-255 per component defined? Seems important for 2D
canvas. Are there tests for that? It also accepts <color> here and
there.

Iwan Riza

unread,
Mar 25, 2020, 5:00:21 AM3/25/20
to Anne van Kesteren, Anders Hartvoll Ruud, Chris Lilley, blink-dev, Felipe Erias Morandeira
--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Felipe Erias Morandeira

unread,
Mar 25, 2020, 5:51:47 AM3/25/20
to blink-dev, ch...@w3.org, felip...@gmail.com
On Wednesday, 25 March 2020 17:31:12 UTC+9, Anders Hartvoll Ruud wrote:

If lab() can't be accurately represented in RGB, would there be any value in shipping lab() support which converted to RGB lossily for painting?

There are JS libraries that already do that, like D3.js (https://github.com/d3/d3-color/blob/v1.4.0/README.md#lab) and chroma.js (https://gka.github.io/chroma.js/#chroma-lab).

Even if the output is clamped to the gamut available to sRGB, having lab() would make it easier for developers to select and manipulate colors. This D3.js Lab Color Picker is a good example.

More in general, being able to choose different methods for interpolating colors would be a valuable design tool. See all the different examples in the D3.js interpolation API and also this comparison between interpolations in different color spaces.

IMHO, it is worth it to explore how an initial implementation of this functionality could help developers. That experience (and the feedback that we could gather) would also (hopefully) help guide us in future steps towards improving the color management in Chromium more generally.

Best,
Felipe

Rik Cabanier

unread,
Mar 25, 2020, 7:47:12 PM3/25/20
to Anders Hartvoll Ruud, Chris Lilley, blink-dev, Felipe Erias Morandeira
It depends what the bit depth of the backbuffer is. 
If chrome renders for higher framebuffe than 8 bit (ie HDR), 8 bits per component won't be enough.

When you say "simply", are you planning on converting the CIE color directly to a CSS color and feed that into the render pipeline?
 
If lab() can't be accurately represented in RGB, would there be any value in shipping lab() support which converted to RGB lossily for painting

It depends what you mean by "accurately". When you map from CIE to device colorspace, the ICC conversion has to do color mapping.
If the CIE color falls outside the device's gamut, you will lose color information.

 

ch...@w3.org

unread,
Mar 26, 2020, 12:52:56 PM3/26/20
to blink-dev, ch...@w3.org, felip...@gmail.com


On Wednesday, 25 March 2020 04:31:12 UTC-4, Anders Hartvoll Ruud wrote:


Can you confirm that dbaron is correct about lab colors not being (accurately) representable in RGB with 0-255 per component, and that we can't simply convert to RGB before painting? We are trying to figure out if our 0-255 per component blink::Color is enough, or if we'd need to change it.

dbaron is correct. If you convert an image with all 16.7 million 8 bit-per-component colors from sRGB to Lab and back, your image will have lost more than half of the unique colors. Lab requires at least 16bits per component. I understand from Tab that Chromium has an internal 16bit/component scRGB available? That would do.

If lab() can't be accurately represented in RGB, would there be any value in shipping lab() support which converted to RGB lossily for painting?
Better than nothing, but for representing display-p3 you need at least 10 bits and for rec2020, 10 or 12.
One of the reasons to ue Lab is to get outside the sRGB gamut.

Felipe Erias Morandeira

unread,
Apr 4, 2020, 3:44:51 AM4/4/20
to blink-dev
Hi,

This is an update on the progress of this proposal. Taking into account the feedback received, it seems important to support wider color gamuts in Chromium before working on lab() and lch(): I am not sure that this can be tackled as a one-volunteer effort, but at least I would like to get the ball rolling.

So, I have been reading a lot of code and doing some experiments. As a starting point, I have written a small proof-of-concept to show that it is possible to make Chromium paint Web elements in colors beyond sRGB, using the API described in "Color Correct Skia". Code is here.

It works by forcing the compositor to paint gradients using shaders with high-definition colors (four floats in the P3 color space), taking advantage that the SkColorSkColor4f conversion maps RGB values to the whole range of the target color space (i.e. #FF0000 is painted as "the reddest red in P3", which is technically incorrect but helpful for this demo).

To check that the colors are indeed in a wider gamut, we can compare them with "Display-P3" colors in Safari/WebKit. And indeed, #FF0000 becomes the same color as color(display-p3 1 0 0), #00FFFF becomes the same as color(display-p3 0 1 1), etc.


Interestingly, the interpolation between color-stops is wrong unless Chromium is forced to use the "Display P3 D65" color profile:


Since Chromium can paint these colors, the challenge then becomes how to tell it when and how to do it. At the moment, my draft of an outline of a plan looks more or less like this:
  • Support ExtendedColors in Blink, similar to what WebKit does
  • Likewise, add support for extended colors in SkColor (or use SkColor4f instead?)
  • Make the compositor use extended colors when they have been defined
And with that in place:
  • parse lab() and lch() in CSS
  • implement LAB gradient shaders in Skia
  • probably fix a lot of other stuff :)
My next explorations will go in the direction of points 1) to 3) above. There is still some work to do on the spec side as well, so I will keep an eye on that.

I am going to be fleshing out this proposal bit by bit, building a better understanding and a more concrete outline of the work to be done.

Best regards,
Felipe
Reply all
Reply to author
Forward
0 new messages