Skip to content

[css-color-4] Allow any color space as part of the interpolation method? #7907

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

Closed
mirisuzanne opened this issue Oct 18, 2022 · 23 comments
Closed

Comments

@mirisuzanne
Copy link
Contributor

Currently, the color-interpolation-method syntax production accepts a limited list of color spaces for interpolation:

<rectangular-color-space> = srgb | srgb-linear | lab | oklab | xyz | xyz-d50 | xyz-d65
<polar-color-space> = hsl | hwb | lch | oklch

That leaves out several of the predefined rgb spaces like display-p3, rec2020, and so on. I imagine that's because all rgb spaces would give a similar (the same?) result to either srgb or srgb-linear - so there's no particular use-case? But I think this makes it harder to teach. If srgb and display-p3 interpolation would have the same result, why not allow authors to use either one? Both are well defined and meaningful, they just happen to be an alias for the same thing. But why should we need to memorize which is the right rgb interpolation space?

@mirisuzanne mirisuzanne added the css-color-4 Current Work label Oct 18, 2022
@svgeesus
Copy link
Contributor

I imagine that's because all rgb spaces would give a similar (the same?) result to either srgb or srgb-linear

All the RGB spaces are defined over the extended range, so all of them with the same or similar gamma will give identical or near-identical results. In particular, display-p3 and srgb have identical transfer functions and will behave identically.

Extended-range srgb-linear (or any other D-65 linear RGB space) will give the identical results to xyz-d65.

But I think this makes it harder to teach. If srgb and display-p3 interpolation would have the same result, why not allow authors to use either one? Both are well defined and meaningful, they just happen to be an alias for the same thing.

This is a fair point.

@brianosman
Copy link
Contributor

I actually came here this morning to ask the inverse question: Why do we offer srgb-linear, xyz-d50 and xyz-d65? I claim that any linear RGB space (regardless of white point) will produce the same answer. Having three options that all resolve to the same behavior is a confusing trap for people that don't understand the color science.

@brianosman
Copy link
Contributor

Ah, just noticed one other thing that you mentioned... srgb and display-p3 would NOT behave identically. Any non-linear color space will give different results, because the gamut transform doesn't commute with the transfer function. It's really just linear RGB spaces that are all equivalent, as far as interpolation is concerned.

@svgeesus
Copy link
Contributor

Any non-linear color space will give different results, because the gamut transform doesn't commute with the transfer function.

You are right. I wasn't thinking clearly.

@svgeesus
Copy link
Contributor

So we basically have two options here:

  1. Reduce the current set down to those that give different results
  2. Expand the current set up to include all defined color spaces

The current set was intended to cover these cases:

a) you want physical linear-light mixing. xyz-d65 is the ideal choice here. srgb-linear will give the same result, as it is defined over the extended range.
b) you want perceptual uniformity. Oklab is the best choice here, with CIE Lab provided as a less good but more familiar option
c) you want perceptual uniformity and care more about avoiding chroma loss than you do about colors swinging out of gamut: so Oklch, or (much worse) CIE LCH
d) you want backwards compatibility more than you want good results, so gamma-encoded sRGB

@mirisuzanne
Copy link
Contributor Author

To me it seems better if authors can use any color space that has the behavior they want - instead of forcing them to memorize which is the 'correct' space for a specific behavior. I don't see what about that would be a 'confusing trap' - or how it would trip people up.

@svgeesus
Copy link
Contributor

The confusing trap is the following line of reasoning:

I'm specifying colors in the shiny display-p3 color space so they look great on modern screens
What color space should I use for color-mix() | gradient interpolation | animation | etc?
Probably should be display-p3 too, right?

@mirisuzanne
Copy link
Contributor Author

I suppose I'm not entirely convinced that limiting the available interpolation spaces actually helps authors know what they're doing and avoid that. You'd still get that line of reasoning with all the allowed spaces - and confusion when a space is not allowed. There's no clear logic to teach for which spaces are allowed, and which are not allowed - or why one space was selected as a representative of a particular interpolation outcome. I don't know how I would teach this besides: yeah, sorry, you'll just have to memorize it, or look it up every time.

@svgeesus
Copy link
Contributor

I don't know how I would teach this besides: yeah, sorry, you'll just have to memorize it, or look it up every time.

This is a fair point. Adding more spaces just makes the teaching burden harder though.

"Why is this space there"
"Well this other space was there, for historical reasons. So we added a bunch of spaces you should never use, to replicate that mistake"

Also, the spec gives specific guidance:

Thus, different color spaces may be more appropriate for each interpolation use case.

In some cases, the result of physically mixing two colored lights is desired. In that case, the CIE XYZ or srgb-linear color space is appropriate, because they are linear in light intensity.

If colors need to be evenly spaced perceptually (such as in a gradient), the Oklab color space (and the older Lab), are designed to be perceptually uniform.

If avoiding graying out in color mixing is desired, i.e. maximizing chroma throughout the transition, Oklch (and the older LCH) work well for that.

Lastly, compatibility with legacy Web content may be the most important consideration. The sRGB color space, which is neither linear-light nor perceptually uniform, is the choice here, even though it produces poorer results (overly dark or greyish mixes).

@mirisuzanne
Copy link
Contributor Author

Huh, if the argument is that we should only provide 'good' options (those listed in the spec), and a 'legacy' option - then I'm curious why hsl/hwb/srgb are all included. They give different results, but none of them are mentioned as 'best' options, and only one is required for 'legacy' reasons.

I'm still a bit torn on that as an approach here - but if we want to go the way of limiting to a recommended set, it seems like we should go all-in on that, and limit the list as much as possible, so there are only a few 'best' options to choose from?

@svgeesus
Copy link
Contributor

if we want to go the way of limiting to a recommended set, it seems like we should go all-in on that, and limit the list as much as possible

I think that makes the most sense.

hsl has one advantage over oklch or lch: the result is never out of gamut for sRGB. And many disadvantages, like lightness being meaningless if the hue is different, and hue being very unevenly spaced, and not supporting colors outside of sRGB. I didn't feel entirely comfortable omitting it, but also not very happy to see it there.

@nex3
Copy link
Contributor

nex3 commented Oct 21, 2022

Maybe this is a naive question, but why does it matter if the result of interpolation is in-gamut for sRGB if browsers will gamut-map it anyway? I understand that gamut-mapping may not always provide ideal results, but neither will sRGB-only (or HSL-only) interpolation.

If you do go the route of limiting the interpolation options to only a certain set of desirable behaviors, maybe it would help clarify to users which interpolation method is for which use-case if you named them after the use-case rather than after one example color space that satisfies that use-case? So linear-light, perceptually-uniform, etc.

@LeaVerou
Copy link
Member

I'm fine adding all color spaces to make this easier to learn.

@svgeesus
Copy link
Contributor

Maybe this is a naive question, but why does it matter if the result of interpolation is in-gamut for sRGB if browsers will gamut-map it anyway?

You are right, it doesn't actually matter, but that is pretty much the sole advantage of manipulating in HSL.

@mirisuzanne
Copy link
Contributor Author

Yeah I still find the one example color space per use-case to be a strange solution that is difficult to remember/teach - and would prefer either naming a limited set of options by their declarative intent (as Natalie suggests), or allowing all color spaces.

@brianosman
Copy link
Contributor

To clarify my 'confusing trap' comment: If we offer the ability to use any space, then I don't think it applies. My concern was with offering a limited menu of choices, and having three of those produce identical results. For people that don't understand the math, they're going to look at that and try to decide which one to use. They might try more than one, and wonder why nothing changes. ("Maybe I'm using it wrong? Maybe I need to use different colors?" Etc...)

I also like specifying intent rather than implementation, but in this case the specification is presumably going to have to map the intents to actual color spaces. Is there any concern if someone finds a tweak (or alternative) to Oklab that's even more perceptually uniform? (Honest question -- the risk of this may be low enough that it's better to embrace today's state of the art in our naming).

@fserb
Copy link
Member

fserb commented Oct 24, 2022

+1 for allowing all spaces even if they map to the same behavior.

What @brianosman is suggesting is a bit orthogonal: allowing behavior-named spaces like "legacy", "best", "perceptual" or whatever.

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.

@mirisuzanne
Copy link
Contributor Author

I suppose authors could also use custom properties to clarify intents, and narrow down their list of 'options' in the same way they do with design tokens:

html {
  --perceptual: oklab;
  --legacy: srgb;
  --linear: xyz-d65;
}

By leaving that to authors, we avoid the issue of locking-in behavior long term. Is there a consensus developing towards allowing all spaces, and using examples/notes to help guide authors towards the reasons they might use one over another?

@svgeesus
Copy link
Contributor

I can live with adding all color spaces. I think it does not make the feature less confusing, by adding a bunch of 'no reason to use these' color spaces. And it adds to the testing burden for no real benefit. But I am okay to go with the majority view.

@mirisuzanne
Copy link
Contributor Author

Agenda+ to discuss with the working group. The tradeoffs are:

  1. Limit the set of color spaces more. This avoids 'unnecessary' options, without locking us into 'intent' names where a better space-for-the-intent might come along in the future. However, the set is somewhat arbitrary-seeming, and the intents are not clear by the name of the space. Authors have to memorize or look up the best option in each case.
  2. Allow any color space. Some of them are redundant, or not particularly useful - but at least we're not making an arbitrary choice, when all of them have meaningful behavior. This seems to be the developing not-quite-consensus, but it's not excellent. Maybe the arbitrary limitation forces authors to consider more carefully?
  3. Declarative names based on author intent. In terms of code legibility, learning, and teaching - this seems like an obvious choice. But as soon as we define the best color space for a given intent, we are likely locked into that choice for the future. If a more perceptually-uniform option comes along, we have no clear way to update our options.

I don't love these options - but I'd like to see this addressed one way or the other before the feature ships.

@LeaVerou
Copy link
Member

Thanks @mirisuzanne for summarizing the options. I'd like to point out that 3 can co-exist with 1 or 2: we could absolutely have lower-level color space options, as well as higher level intent-based keywords that could change in the future. Authors who want control would use the former. Documentation could include the current mapping of intent-based keywords to color space keywords, so that authors can switch to color space keywords before shipping if they want that kind of control.

@svgeesus
Copy link
Contributor

I agree with @mirisuzanne that the emerging slight consensus seems to be to allow any of them, and with @LeaVerou that this does not preclude adding declarative names later. Meanwhile the spec does have guidance on what to pick for different desired results.

This does increase the testing burden, but not by much.

Should I go ahead and make the spec edits for "allow all"?

@mirisuzanne
Copy link
Contributor Author

Sounds good to me.

aarongable pushed a commit to chromium/chromium that referenced this issue Mar 28, 2023
Initially these were implemented as distinct ideas. As we've begun to
unify creation and conversion methods for blink::Color, it makes less
and less sense to keep them separate.

ColorInterpolationSpace was a subset of ColorSpace, so the only logic
that needs to be added is to throw if an interpolation is attempted
in one of the handful of ColorSpaces that are NOT
ColorInterpolationSpaces (display-p3, a98-rgb, prophoto-rgb and
rec2020). There is already talk underway to turn these into spaces
for interpolation anyway:

w3c/csswg-drafts#7907

Also the sRGBLegacy ColorSpace is used more explicitly as it is distinct
from sRGB.

Change-Id: Iebe1e7b7abce26cb4c606f1787995aa50d5e6d0b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4327275
Reviewed-by: Justin Novosad <junov@chromium.org>
Commit-Queue: Aaron Krajeski <aaronhk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1123288}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants