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] What if legacy colors *also* interpolated in Oklab by default? #7948

Open
LeaVerou opened this issue Oct 24, 2022 · 31 comments
Open

Comments

@LeaVerou
Copy link
Member

LeaVerou commented Oct 24, 2022

Right now, css-color-4 allows UAs to handle interpolation between legacy colors in gamma-encoded sRGB:

However, user agents may handle interpolation between legacy sRGB color formats (hex colors, named colors, rgb(), hsl() or hwb() and the equivalent alpha-including forms) in gamma-encoded sRGB space. This provides Web compatibility; legacy sRGB content interpolates in the sRGB space by default.

I wrote this as a may to give UAs the choice of not doing this, but so far implementations seem to have all done this.
We have accepted that we have to live with this wart because of webcompat, but I'm not sure we have sufficiently examined the implications of the opposite. Can we actually examine the web compat implications of doing away with this clause? What if we moved all color interpolation on the Web away from gamma-encoded sRGB?

There is precedent of changing rendering of existing content when the new way is universally better (text-decoration-skip, I'm looking at you), so this shouldn't be a non-starter, the bar is just high for what kind of changes are acceptable, and I'd argue this may pass that bar. Interpolating colors in Oklab never produces worse results (I challenge anyone who disagrees to find me an example where gamma-encoded sRGB interpolation produces better results, you can play with the colors here in Safari TP).

The only case I can think of where gamma-encoded sRGB interpolation is desirable is color pickers. However,

  • the gradients in color pickers are only a visual aid, but the actual picked/displayed color would not be affected
  • I think this would only affect RGB color pickers (like this), and most color pickers use a hue-based model (HSL, HSV, etc). I really struggled to find one that actually shows RGB visualizations. The hue-based ones are still implemented through segments of gamma-encoded sRGB interpolated gradients (since that was the only gradient available), but the segments are so small I don't believe there will be any difference.
  • There should be wording in that spec that forbids UAs from implementing this without implementing the syntax to control interpolation space, so that authors can always revert to the previous behavior for the handful of cases where gamma-encoded sRGB interpolation is desirable.

It would be nice if gradients could just do the right thing by default without people needing to know about color spaces, and having to type in oklab in their gradients like a magic incantation until the end of time. 😕

Examples

red to lime:
image

red to aqua:
image

red to fuchsia:
image

aqua to fuchsia:
image

lime to fuchsia:
image

lime to blue:
image

blue to gray:
image

white to blue:
image

white to black:
image

@svgeesus
Copy link
Contributor

(I challenge anyone who disagrees to find me an example where gamma-encoded sRGB interpolation produces better results, you can play with the colors here in Safari TP)

Thanks for the demo! I had expected it to also work in Chrome Canary 108 (with experimental flag), but it didn't which I found surprising.

@LeaVerou
Copy link
Member Author

(I challenge anyone who disagrees to find me an example where gamma-encoded sRGB interpolation produces better results, you can play with the colors here in Safari TP)

Thanks for the demo! I had expected it to also work in Chrome Canary 108 (with experimental flag), but it didn't which I found surprising.

It appears to be parsing the syntax, but not actually applying it. I guess that must be temporary, otherwise it would break feature detection! @sesse could clarify.

@romainmenke
Copy link
Member

I think this is very risky.

(I challenge anyone who disagrees to find me an example where gamma-encoded sRGB interpolation produces better results,

I don't think that is the right question.
All current usage should be assumed to be deliberate, matching some design/intention.

A preprocessor like PostCSS easily allows you to make in oklab a default without breaking backwards compat.

@Loirooriol
Copy link
Contributor

Can you post a screenshot of the demo to see the better results? I tried WebKitGTK and in oklab parses but I don't see the difference.

@sesse
Copy link
Contributor

sesse commented Oct 24, 2022

I guess that must be temporary, otherwise it would break feature detection! @sesse could clarify.

I pulled out of CSS Color a long time ago, so I don't have anything to do with Chrome's implementation, sorry. (I ended up doing nesting instead.)

@LeaVerou
Copy link
Member Author

Can you post a screenshot of the demo to see the better results? I tried WebKitGTK and in oklab parses but I don't see the difference.

I just added some to the first post.

@svgeesus
Copy link
Contributor

So where are we on this? I saw @fserb saying that Chrome won't change gradients that currently interpolate in sRGB because backwards-compat is prioritized over better results.

@LeaVerou
Copy link
Member Author

My understanding is that Chrome at some point tried interpolating in linear RGB by default and decided the backwards compat cost was too much; but that's very different than interpolating in OkLab…

Where is that comment by @fserb ?

@svgeesus
Copy link
Contributor

@fserb wrote (in the context of which interpolation spaces should be allowed and whether to add intent-based names which might change over time):

I'm not convinced that we could do this: right now, we are not changing the default behavior from legacy-srgb, because that would break content. If we can't change gradients without breaking content, then having "intent-names" would be bad, because we would have the same problem when trying to change them in the future. I think this forces us out of intent and into explicit opt-ins.

@svgeesus
Copy link
Contributor

My understanding is that Chrome at some point tried interpolating in linear RGB by default and decided the backwards compat cost was too much; but that's very different than interpolating in OkLab…

Here is a three-way comparison: srg-linear, srgb, and oklab

@svgeesus
Copy link
Contributor

svgeesus commented Feb 7, 2023

@fserb could yo confirm whether your backwards-compat concern was "we can't change to oklab to interpolate legacy" and not "we can't change to srgb-linear to interpolate legacy" because, as @LeaVerou pointed out, those are very different. I agree that interpolating in srgb-linear (which would be tempting if your colors are stored like that internally) would be a non-starter because it is very perceptually non-linear. While srgb and oklab are much more comparable, with srgb tending to be darker and a bit less saturated at the midpoint.
comparison

@romainmenke
Copy link
Member

@svgeesus can you place srgb and oklab next to each other?
Placing a larger difference in between doesn't present the proposed change accurately.

@svgeesus
Copy link
Contributor

svgeesus commented Feb 7, 2023

Here you go simple edit

image

@romainmenke
Copy link
Member

Thank you, much easier to judge the outcome :

Screenshot 2023-02-07 at 19 27 48

@astearns astearns added this to Overflow in March 2023 VF2F Mar 9, 2023
@astearns astearns moved this from Overflow to Wednesday - Mar 22 in March 2023 VF2F Mar 9, 2023
@kizu
Copy link
Member

kizu commented Mar 17, 2023

Question: would it be possible to introduce a new CSS property that would set the default interpolation for the colors? Like, interpolation-color-space or something?

This way it would be possible to not break backwards-compat, but anyone who would want to just always use the more modern version, could just put this property in their reset. Something like :root { interpolation-color-space: oklab; } if it would be inherited, or * { … } otherwise?

@LeaVerou
Copy link
Member Author

Question: would it be possible to introduce a new CSS property that would set the default interpolation for the colors? Like, interpolation-color-space or something?

This way it would be possible to not break backwards-compat, but anyone who would want to just always use the more modern version, could just put this property in their reset. Something like :root { interpolation-color-space: oklab; } if it would be inherited, or * { … } otherwise?

It's not that simple, because you typically want a different interpolation color space depending on the use case (e.g. gradients vs transitions vs compositing etc).
I believe there is another issue where we discuss this, but I can't find it now.

@astearns
Copy link
Member

I believe there is another issue where we discuss this, but I can't find it now.

Perhaps #7035?

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-color-4] What if legacy colors *also* interpolated in Oklab by default?, and agreed to the following:

  • RESOLVED: change specification say browser MUST use OKLab color interpolation for all colors, including legacy colors
The full IRC log of that discussion <chris> q+
<Rossen_> ack chris
<emeyer> chris: For non-legacy colors, implementation should interpolate in oklab
<emeyer> …The spec says implementations MAY interpolate in sRGB if all the colors are legacy colors
<emeyer> …Lea raised, why not make them all do it in oklab?
<lea> q+
<emeyer> …We did some tests, and for some colors there’s a big difference
<emeyer> lea: I think it’s an obvious improvement in every color pair we tried
<emeyer> …There is precedent for doing this in places like text-decoration-skip
<emeyer> …It makes for an easier rule to learn and remeber
<emeyer> …oklab produces better gradients
<emeyer> …The only problem I could think of is color pickers
<emeyer> …I can’t remember the proposed solution to this
<emeyer> …The Chrome team has said they’re kind of apprehensive because they tried to do linear RGB and there were problems
<emeyer> …This isn’t the same because linear RGB isn’t perceptually uniform
<emeyer> chris: In Chrome, the colors are stored in premultiplied linear RGB
<emeyer> …I wanted to know whether they said they can’t change because of that trial, or because of the proposal
<emeyer> lea: I heard from someone on Chrome team they trioed linear RGB and had poor results
<emeyer> chris: As expected
<emeyer> bramus: I don’t think anyone here can address this directly, but I’ll poke the correct people for a response
<fremy> I would note that there might be images associated to the gradients
<emeyer> Rossen: In absence of that, is there a resolution you want to take here that will ideally be something that would work?
<emeyer> lea: Are there any objections to this, involving actual cases where this would be worse?
<emeyer> emilio: Does this only affect gradients, or does it also affect animation?
<emeyer> lea: That’s up to us; I believe it’s currently about gradients only
<emeyer> emilio: Applying to animations would be trickier because it affects computed styles
<TabAtkins> yeah i'd be relatively bothered by interpolation and gradients not working the same
<emeyer> chris: The spec is about interoplation, so it would apply to everything
<emeyer> emilio: That’s a bit trickier, but it might work
<lea> q+
<emeyer> …I’d be surprised if there are no pages that rely on this, but it might be a better default
<lea> q-
<emeyer> chris: Although it’s true a gradient defined as a gradient is better, I’m concerned we’ll get “why is my page lighter?”
<lea> q+
<emeyer> emilio: It’s good to change the default consistently
<emeyer> …I agree it’s a better default, but compat is a concern
<ydaniv> what about filters?
<emeyer> …Gradients would be better regardless, I think
<lea> ydaniv: filters are defined entirely differently, they don't use interpolation
<emeyer> …Changing the default for everything is probably worth a try
<Rossen_> ack lea
<emeyer> lea: I want to clarify that making this the default doesn’t make it mandatory
<emeyer> …There’s a way to specify the interpolation space for gradients, and will be able to apply to other things
<emeyer> …So there’s an escape hatch
<emeyer> chris: This comes down to, is this an opt-in or an opt-out?
<emeyer> …For unmaintained pages, what happens?
<plinss> q+
<emeyer> Rossen: opt-in would be safer, yes?
<emeyer> chris: I agree
<bramus> q+
<emeyer> plinss: The issue of a page becoming lighter isn’t a big deal except in cases where CSS color needs to match image color
<Rossen_> ack plinss
<emeyer> …Want to be sure we’re taking that into consideration
<Rossen_> ack bramus
<emeyer> bramus: I vote for opt-in; authors will be surprised if colors change
<lea> q+ to point out the other huge precedent for changing color display
<emeyer> Rossen: +1 from me
<emeyer> …colors can often be a branding issue
<chris> q?
<fantasai> +1 from me to plinss's point, that it's important for the endpoints and not so much for the middle
<Rossen_> q
<Rossen_> ack lea
<Zakim> lea, you wanted to point out the other huge precedent for changing color display
<emeyer> lea: This reminded me, we have a more relevant precedent where we changed to interpret legacy CSS colors in sRGB, so what what red meant changed (for example)
<emeyer> …That’s a much bigger change than what we’re discussing here
<Rossen_> ack fantasai
<emeyer> …only midpoints in a transition will change
<TabAtkins> color management only affected people with good screens, tho
<emeyer> fantasai: I support Lea’s proposal; I think midpoint changes will be an improvement
<florian> +1
<miriam> +1
<emeyer> …There’s a lot of shift in colors depending on monitor calibration etc.
<emeyer> Rossen: So do we make this opt-in, something we can drop later, or make it opt-out?
<emeyer> lea: Opt-in bascially means no change
<emeyer> fantasai: I think we should change the default for the web to be the better interpolation
<emeyer> lea: Current language is that browsers MAY do this; proposal is to change this to MUST
<emeyer> Rossen: Or maybe SHOULD
<lea> s/is to change this to MUST/is to change this to MUST ...or at least SHOULD?/
<emeyer> lea: Also resolutions are not binding, we can always reverse if investigations reveal it’s a bad idea
<emeyer> florian: I’m not sure what we gain with a SHOULD
<emeyer> …If we have a good reason not to do something, we should roll this back
<emeyer> …I think MUST is appropriate
<emeyer> lea: Maybe SHOULD is better for low-powered devices where oklab computation is harder than calculating the RGB values on hand
<emeyer> plinss: I would argue devices like that probably won’t support this sort of thing
<astearns> +1 to MUST
<fantasai> +1 to requiring OKLab interpolation
<emeyer> Rossen: Objections to using MUST on using oklab?
<emeyer> (silence)
<emeyer> RESOLVED: change specification say browser MUST use OKLab color interpolation for all colors, including legacy colors
<emeyer> s/browser/browsers/

@romainmenke
Copy link
Member

romainmenke commented Mar 22, 2023

I still think this is a bad idea.
Please reconsider this change.

The benefits and downsides haven't been weighted properly in my opinion.

It has only been demonstrated that oklab is a better interpolation color space.
It hasn't been demonstrated that changing this would be a good thing for CSS authors or end users.

Reasons not to do this :

  • what if a future color space is even better than oklab? do we change to that? If so, why should users ever write a gradient without an explicit interpolation color space. They would opt-in to future breakage by omitting the color space.
  • authors already have plenty of tools to reduce typing and make it easier to always opt-in to a specific interpolation color space. We don't need to make a breaking change to help authors. (tools like stylelint exist for this very reason)
  • this change is known to affect existing pages, please be more careful with backwards compat.

I think midpoint changes will be an improvement

This is highly subjective.

srgb interpolations tend to have darker midpoints.
Making these lighter for example has an effect on contrast with elements on top of a gradient.

A page that is accessible before this change could become inaccessible.
That is objectively worse.

@fserb
Copy link
Member

fserb commented Mar 23, 2023

Sorry, for the delay in replying. I was away.

I agree with @romainmenke. This is not about the gradients being better looking (they are), but as mentioned before, they can have unexpected side effects on contrast and other elements close to the gradient.

Here's an example that I made using the codepen above:
image

It's a simple #F00 to #0F0 gradient with the text color set to #CFA903. This is clearly readable on the current default and unreadable on oklab. This is one of many potential types of problems we will have if we change the default.

The "opt-in" change is relatively simple (just add in oklab on the gradient) and much safer from breaking existing sites.

@LeaVerou
Copy link
Member Author

@fserb This example is specifically crafted for this purpose, but how prominent is this problem in the wild? Also do note that even in the first example, contrast is already insufficient.

As I pointed out in the call, there is precedent for us making a change with similar dangers, when we moved from device RGB to sRGB. I don't recall anyone having text readability concerns then, and arguably that was an even more impactful change (since it also affected spot colors, not just transitions between them).

@romainmenke
Copy link
Member

romainmenke commented Mar 23, 2023

As I pointed out in the call, there is precedent for us making a change with similar dangers, when we moved from device RGB to sRGB. I don't recall anyone having text readability concerns then, and arguably that was an even more impactful change (since it also affected spot colors, not just transitions between them).

Correct me if I am wrong, but the change from device RGB to sRGB was homogenous across any colors defined in CSS right?

That change made CSS defined colors more consistent and predictable overal.
It made it easier to work with color on the web.

This change however doesn't do any of that.
It makes gradients more visually pleasing, but authors can already opt-in to the those without breaking backwards compat.

I don't think these two changes are actually similar in nature.


This example is specifically crafted for this purpose, but how prominent is this problem in the wild

The same is true for the inverse.
Any examples in favor of this change are crafted to show visually pleasing gradients out of context. But it is the context that is the important part.

It hasn't been demonstrated that authors want this change.

@LeaVerou
Copy link
Member Author

I’m not sure what future you are reacting so strongly against. Do you think that UAs will just roll out this change because we changed MAY to MUST, without doing careful vetting? That's exactly what origin trials and flags are for. You even seem to agree that it's a better interpolation mode, so doing research into compat is the next logical step. If you come across any real-world use cases where this produces worse results, by all means please share them. But if the concerns are purely theoretical, I will remind you that we have a WG resolution and I personally will not engage in this further.

@dbaron
Copy link
Member

dbaron commented Mar 23, 2023

Do you think that UAs will just roll out this change because we changed MAY to MUST, without doing careful vetting?

You might be surprised by how often that happens, although I don't think it will in this case.

That's exactly what origin trials and flags are for.

I don't think either are particularly helpful here, since it's the sort of change where breakage seems unlikely to be detectable by sources other than user-reported bugs. (That said, it's possible reverse origin trials might be useful if there's a sufficiently small number of affected sites to proceed with the change and it's hard for some affected sites to be fixed quickly.)

@romainmenke
Copy link
Member

@LeaVerou

I’m not sure what future you are reacting so strongly against.

I didn't think I was reacting overly strong here.
Written communication for non-native english speakers can lack nuance.
If I didn't express myself correctly, then I apologize, this was not my intention.

I will remind you that we have a WG resolution and I personally will not engage in this further.

I don't think it is helpful or welcoming if the slightest friction escalates like this.
I hope we can keep this conversation open to feedback?


My only concern here is that backwards compat is given sufficient weight here given the small gains of this change. Authors only need to type two words to opt-in.

To me it felt as if backwards compat wasn't given enough weight.
But as that the next step is to research exactly that, then I think there is no issue here :)

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-color-4] What if legacy colors *also* interpolated in Oklab by default?.

The full IRC log of that discussion <emeyer> chris: We resolved but we got some pushback on github; people thought we were too hasty and they were worried about backward compatibility
<lea> q+
<emeyer> …The current issue is, are we sticking with our original resolution, are we backpedaling on it, will there be an origin trial?
<fserb> q+
<emeyer> lea: My recollection is we didn’t just resolve to use okLAB everywhere, we resolved to explore the potential implications
<emeyer> Rossen: I would be surprised if people are pushing back on us being more careful
<fantasai> the resolution definitely wasn't worded that way...
<emeyer> fserb: I don’t think this was well captured on the issue; that wasn’t my understanding
<emeyer> …Is this too much for an origin trial? It feels like it has the potential to break sites in weird ways
<emeyer> …There’s not firm ground here
<emeyer> …It felt a little bit too much, even for an origin trial, because there are expectations of what colors look like
<lea> q+
<emeyer> Rossen: Origin trials are the best way we have to test safely
<emeyer> …Anything we introduce can have the effect of changing things in ways authors don’t expect
<emeyer> …If this is an extension of an existing features, there are different risks that can be taken
<emilio> q+
<emeyer> …But anything introduced generally needs an origin trisl to make sure we don’t upset expectations
<Rossen_> q?
<emeyer> …This doesn’t seem too heavy in terms of trial
<emeyer> dbaron: I don’t think this is the sort of thing origin trials are good at
<emeyer> …Trials are good for things like PIAs
<emeyer> …This is making a change that might be a compatbility problem that might break sites
<emeyer> s/PIAs/APIs/
<lea> wouldn't deploying the change on beta/canary channels address this?
<emeyer> …There is the concept of a reverse origin trial, but I think that’s useful when we’re more strongly committed to making breaking change but might need a bumpy rollout
<Rossen_> ack dbaron
<emeyer> …I didn’t get the sense we were that committed to it
<fserb> +1 to what dbaron said
<emeyer> emilio: I agree with fserb
<emeyer> s/fserb/dbaron/
<Rossen_> ack emeyer
<Rossen_> ack emilio
<emeyer> …In general, an origin trial seems do-able, but I was going to ask if this has to be an origin trial as we know them
<emeyer> lea: Would deploying on beta or canary channels address this?
<fserb> q+
<emeyer> …In my experience, when authors do gradients, they have expectations about the color stops, not what’s between the stops
<emeyer> …Also, how does a reverse origin trial work?
<emeyer> iank_: Generally it’s when we’re making a known breaking change, and we want time to roll it out
<emeyer> …An origin can opt out while they work to fix their site
<Rossen_> q?
<emeyer> …Generally only used when we really really want to do something, as they can drag on for quarters or years
<Rossen_> ack lea
<Rossen_> ack fserb
<chris> q?
<emeyer> fserb: I agree authors usually don’t want a particular value outside stops, but the gradients are different enough that even the stops can look odd
<emeyer> …Colors could get darker or lighter than expected
<emeyer> fantasai: I support Lea’s too points: the best way is to roll out through beta channels and collected feedback, and also that changing interpolation isn’t nearly as bad as changing stops
<emeyer> …Authors who really care about the interpolation tend to add color stops to force them
<lea> +1 fantasai
<chris> I agree that if a specific matching color is relied on, there will be a color stop there
<emeyer> …We have to consider cases where this will make things better, not just those where things will be worse
<emeyer> …We expect this change to make the web better overall
<emeyer> Rossen_: Is there anything we need to do about the previous resoluion?
<lea> q+
<emeyer> chris: Do we stick the previous resolution in the spec, or put it in with caveats?
<emeyer> lea: In theory, fserb’s point about breakage is possible if not likely, but we should explore that
<emeyer> …It sounds to me like we have consensus that we should do this, but perhaps we should make the resolution more explicit that we want to explore this
<emeyer> Rossen_: I agree with you there
<Rossen_> ack lea
<emeyer> fantasai: If we’re not going to do this, then we can’t put it in the specification, so we need an implementor to say they’re willing to do it
<fserb> q+
<emeyer> Rossen_: Any implementor interest?
<lea> How could implementors be interested in testing this if we have no idea *how* to test? They cannot commit to an unknown amount of work
<lea> Op, I guess I was wrong :)
<emeyer> emilio: It should be relatively easy to prototype and test out
<fantasai> Release it in beta, and see what happens
<fantasai> If there aren't lots of bugs reported, then we should be fine to release more broadly
<emeyer> fserb: I’d like to see a way to measure the impact of this
<lea> q?
<lea> q+
<emeyer> …How would we extrapolate from beta to stable?
<Rossen_> ack fserb
<emeyer> …Not against this on principle
<emeyer> lea: Another testing channel could be to tack it onto a flag that a lot of developers already have enabled
<fantasai> s/have enabled/have enabled, e.g. experimental web platform features flag/
<fantasai> +!
<fantasai> +1
<emeyer> Rossen_: There was some implementor interest, and how we implement testing is really their call
<emeyer> …With that said, it sounds like the text that goes into the spec is the previous resolution
<Rossen_> q?
<emeyer> chris: Okay, thanks
<Rossen_> ack lea
<emeyer> Rossen_: So, no change here

@heycam heycam removed the Agenda+ label Jun 6, 2023
svgeesus added a commit that referenced this issue Jul 5, 2023
…ab color interpolation for all colors, including legacy colors #7948
@svgeesus svgeesus closed this as completed Jul 5, 2023
@romainmenke
Copy link
Member

romainmenke commented Jul 5, 2023

@svgeesus Was there a resolution to change this, or was there a resolution to investigate changing this?

I assumed the second from the minutes, but now I am unsure.


Edit : re-read the minutes and I think I understand it better now.
It was the previous resolution that was being discussed.

The final resolution in these minutes was to change the specification.

@svgeesus
Copy link
Contributor

svgeesus commented Jul 6, 2023

The final resolution in these minutes was to change the specification.

Yes. Which amounted to commenting-out a "may interpolate in sRGB' and flipping a paragraph about how to get the old behavior.

@fantasai fantasai removed this from By Theme in Agenda Scratchpad Dec 13, 2023
@svgeesus
Copy link
Contributor

I see that there is a WPT which tests the old behavior (legacy syntax colors interpolate in sRGB)

https://github.com/web-platform-tests/wpt/blob/master/css/css-images/gradient/legacy-color-gradient.html

I guess that should be reworded and the reference should be linked with a "must not match".

@mysteryDate you wrote that test (which was correct, at the time) do you agree?

@mysteryDate
Copy link

I guess that should be reworded and the reference should be linked with a "must not match".

Or we could just change the reference for that test to oklab-gradient-ref.html, because now the gradient must be in oklab, right?

@svgeesus
Copy link
Contributor

Or we could just change the reference for that test to oklab-gradient-ref.html, because now the gradient must be in oklab, right?

Yes, right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

No branches or pull requests