w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.43k stars 652 forks source link

[css-color-4] a new property to limit to a specific color gamut #10038

Open romainmenke opened 6 months ago

romainmenke commented 6 months ago

see : https://github.com/w3c/csswg-drafts/issues/9449#issuecomment-1980976323

@ccameron-chromium said :

If an author specifies content that is far outside of what their screen can reproduce, then there is no way to avoid having them be surprised when that content is accurately rendered on a more capable screen.

This is very much a "the only winning move is not to play" situation. We shouldn't be giving authors tools where it is extremely easy to unintentionally specify such colors. But we did, in the lab, lch, oklab, and oklch spaces. The oklab and oklch spaces are excellent for perceptually uniform interpolation, but they are dangerous for color manipulation, because there are no guardrails for staying in-gamut. The relative-color syntax exacerbates this.

The problem that I want for us to focus on solving here is how to avoid having authors specify colors that are far beyond their display's capability to produce.

If we don't solve that problem then authors will inevitably face the above-described surprise.

If we don't solve that problem then we also have to solve the problem of assigning meaning to colors that are physically meaningless or far beyond the capabilities of any current display.


This comment was made in the context of gamut mapping for colors when those colors go beyond the device capability.

While I don't agree with that line of thinking, I do think there is something here and I want to explore it from a different perspective.


There is a disconnect between:

Authors can easily write CSS that produces color values that are outside specific color gamuts. With interpolation, animations, relative color, ... this can often happen without the author noticing at the time of writing that specific code.

Should it be possible for authors to force a document and/or element to gamut map all colors to a specific gamut?

Maybe through a new property :

:root {
  max-color-gamut: display-p3;
}

Authors would then be able to use things like interpolation in lch without having to worry about unexpected outcomes on future hardware.

It gives you access to the color models behind oklch, lch, ... without having to think about what happens when values go beyond your design constraints.

svgeesus commented 6 months ago

So to clarify, this is a gamut map on all computed color values, before the mapping to the actual display?

tabatkins commented 6 months ago

Yes.

foolip commented 6 months ago

Would the default value be none, or some specific gamut?

romainmenke commented 6 months ago

I think it must be none as it is unlikely to be changed in the future for web compat reasons.

If authors want to limit to a specific gamut then they must state so explicitly.

foolip commented 6 months ago

Thanks for confirming @romainmenke!

svgeesus commented 6 months ago

Would this property define how colors outside the specified gamut are gamut mapped into it?

Does it apply to all elements?

Can it be animated?

tabatkins commented 6 months ago

Would this property define how colors outside the specified gamut are gamut mapped into it?

I imagine so, yes. Not much use in guaranteeing predictable colors if different browsers can still render differently.

Does it apply to all elements?

Yes, it would need to.

Can it be animated?

I don't see a compelling reason to allow that. It should just animate discretely.

svgeesus commented 6 months ago

I don't see a compelling reason to allow that. It should just animate discretely.

Same here, just wanted to check.

romainmenke commented 5 months ago

Thinking about this more, this same property could also be an opt-out of gamut mapping.

Values could be:

Where:

If clipping is valuable to some an opt-out could be a way to move forwards.

jamesnw commented 5 months ago

none is different than clip, I think. none would tell the user agent to leave the color as is, outside of the display gamut, essentially leaving it up to the display hardware (or whatever graphics API the user agent is interacting with) to clip, do its own gamut mapping, or error in some way.

I think we would need multiple values, with some shorthands. Essentially, we are defining a path to a color that can be displayed on a user's device, so we need method destination gamut, method destination gamut, .... We must end on the device gamut or smaller (unless we want to allow a none escape hatch?) so we need to implicitly add those final steps if the user doesn't specify it.

For instance-

Instead of clip and auto, it could be useful to have intent-based names, for instance preserve-contrast instead of auto and preserve-chroma instead of clip?

This does raise the burden on implementers to implement multiple algorithms, mapping to multiple gamuts.