Skip to content

[css-color-4] Expand the concept of analogous components to analogous sets of components to minimize none0 conversions #10210

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

Open
LeaVerou opened this issue Apr 15, 2024 · 8 comments
Labels

Comments

@LeaVerou
Copy link
Member

(This came out of my comment here: #10151 (comment) )

Currently, css-color-4 defines that none values will be carried forward to analogous components. Basically, even when converting to different color spaces, if there are analogous components, they will become none.

Essentially what this does, is attempt to divide the components into rough sets of dependencies and try to preserve author intent as much as possible.
Sure, they’re not entirely orthogonal, and e.g. tweaking hue in HSL does affect chroma and lightness in oklch, but it's the lesser of two evils, the other evil being converting none to 0.

To that goal, I can see a few improvements we can make to minimize none0 conversions even more:

  1. Instead of analogous components, word the prose around analogous sets of components. The current analogous components are just sets of size 1.
  2. If two color spaces have analogous components, the components remaining after you remove all analogous components, are an analogous set. Meaning, if Lab L is analogous to OKLch L, this means Lab a,b are analogous to OKLCh c, h., so converting e.g. oklch(50% none none) to lab yields lab(42 none none).
  3. The set of all components is analogous in every color space (basically [css-color-5] Colors where all channels (except) alpha have a value of none #10203 )

Not sure if this can be considered editorial, or we'd need WG resolution. @svgeesus ?

@LeaVerou LeaVerou added the css-color-4 Current Work label Apr 15, 2024
@LeaVerou LeaVerou changed the title [css-color-4] Expand the concept of analogous components to analogous _sets_ of components to minimize none0 conversions [css-color-4] Expand the concept of analogous components to analogous *sets* of components to minimize none0 conversions Apr 15, 2024
@LeaVerou LeaVerou changed the title [css-color-4] Expand the concept of analogous components to analogous *sets* of components to minimize none0 conversions [css-color-4] Expand the concept of analogous components to analogous sets of components to minimize none0 conversions Apr 15, 2024
@LeaVerou
Copy link
Member Author

I actually just realized a pretty important reason to do this: it means the result can be consistent regardless of the conversion path.

For example, let’s take a conversion from sRGB to LCh.
The conversion path using XYZ D65 as a connection space is as follows: sRGB → Linear sRGB → XYZ D65 → XYZ D50 → Lab → LCH

Suppose we’re converting white.
white in XYZ D50 is color(xyz-d50 0.9643 1 0.8251) which is lab(100 none none).
a and b have no analogous components, so when converted to LCh they are converted to lch(100 0 0).
However, if we consider them an analogous set, then can be converted to lch(100 none none).

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-color-4] Expand the concept of analogous components to analogous sets of components to minimize `none` → `0` conversions, and agreed to the following:

  • RESOLVED: Also any set of analogous components are
The full IRC log of that discussion <fantasai> lea: mapping between components of analogous color spaces is well-defined in the spec
<fantasai> lea: e.g. mapping green to green, ligthness to lightness, etc.
<fantasai> lea: if analogous component exists in other color space, after conversion none is preserved
<fantasai> lea: we convert none to zero, and then convert, and then put none back
<fantasai> lea: want to expand the idea
<fantasai> lea: if lightness is none and convert from labl to oklch
<fantasai> lea: lightness is still none
<fantasai> lea: but if lightness is a specific number and a/b are none they would become zero
<fantasai> lea: what this concept defines is .. if you split the components into sets that correspond
<fantasai> lea: then what remains is also analogous
<fantasai> lea: so a+b is analogous to c+h
<fantasai> lea: this mainly makes a difference for lab to lch
<fantasai> lea: or colors where all are none
<fantasai> lea: that would be an analogous set
<fantasai> lea: that's logically consistent
<dbaron> makes sense
<fserb> q+
<lea> q?
<fantasai> fserb: will you describe in the spec in those terms, or actually list all the combinations?
<ChrisL> I think these analogous sets make sense
<dbaron> (it doesn't sound to me like there's much of an explosion... I think)
<fantasai> lea: combinatorial explosion. So anything that remains after subtracting the analogous components is (as a set) an analogous component
<lea> PROPOSED RESOLUTION: Expand concept of analogous components to analogous *sets* of components.
<fantasai> PROPOSED: The components that remain after removing the anlogous components are (as a set) an analogous component.
<dbaron> (including all components being none being analogous for all color spaces)
<fserb> +1
<fantasai> RESOLVED: Also any set of analogous components are

@svgeesus
Copy link
Contributor

@LeaVerou could you propose specific spec text? In particular I am not understanding "all components being none being analogous for all color spaces".

@LeaVerou
Copy link
Member Author

@LeaVerou could you propose specific spec text? In particular I am not understanding "all components being none being analogous for all color spaces".

I’ll need to think more about specific spec text but that sentence basically means that if all three components are none, then all components of the resulting color are none regardless of what the source and destination color space is. E.g. rgb(none none none / 50%) becomes oklab(none none none / 50%).

@yisibl
Copy link
Contributor

yisibl commented Apr 22, 2025

@LeaVerou As proposed here, the gradient below would render green?

Currently Chrome, Safari, and Firefox all render as a black to green gradient.

.test {
  background: linear-gradient(in oklab, rgb(none none none), green );
  width: 200px;
  height: 200px;
}

@svgeesus
Copy link
Contributor

Currently Chrome, Safari, and Firefox all render as a black to green gradient.

Right, because they are converting none to 0 too early

@romainmenke
Copy link
Member

I am unsure if too early is the right way to describe this.
They do follow the spec correctly in this case: https://drafts.csswg.org/css-color-4/#interpolation-missing

In the course of converting the two colors to the interpolation color space, any missing components would be replaced with the value 0.

Thus, the first stage in interpolating two colors is to classify any missing components in the input colors, and compare them to the components of the interpolation color space. If any analogous components which are missing components are found, they will be carried forward and re-inserted in the converted color before premultiplication, and before linear interpolation takes place.

Because there are no analogous components between rgb and oklch, nothing is carried forward and re-inserted. Interpolating with black is correct as per the current specification.

Or is there another part of the specification that also comes into play and that makes the current implementation incorrect?

Is the proposed change (and resolution) still a change we can make given that there seems to be interop for the current specification?

@svgeesus
Copy link
Contributor

I am unsure if too early is the right way to describe this.
They do follow the spec correctly in this case: https://drafts.csswg.org/css-color-4/#interpolation-missing

Yes, agreed. Hence this issue; the goal is to preserve none more than the current spec allows. So earlier than we want would be more precise.

Is the proposed change (and resolution) still a change we can make given that there seems to be interop for the current specification?

Not clear, but remains a possibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants