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] How to handle out-of-bounds legacy srgb values? #10087

Open
Loirooriol opened this issue Mar 14, 2024 · 0 comments
Open

[css-color] How to handle out-of-bounds legacy srgb values? #10087

Loirooriol opened this issue Mar 14, 2024 · 0 comments
Labels
css-color-4 Current Work css-color-5 Color modification

Comments

@Loirooriol
Copy link
Contributor

Loirooriol commented Mar 14, 2024

Consider this testcase:

<!DOCTYPE html>
<style>
#a { width: 200px; height: 200px; animation: a 2s -1s paused linear(0, -1, 1) }
#b { width: 100px; height: 100px; animation: b 2s -1s paused linear }
#c { width: 100px; height: 100px; animation: c 2s -1s paused linear }
@keyframes a {
  from { background-color: rgb(75, 0, 0) }
  to { background-color: rgb(0, 255, 0) }
}
@keyframes b {
  from { background-color: inherit }
  to { background-color: rgb(0, 255, 0) }
}
@keyframes c {
  from { background-color: /* Set in JS */ }
  to { background-color: rgb(0, 255, 0) }
}
</style>
<div id="a">
  <div id="b"></div>
  <div id="c"></div>
</div>
<pre><script>
document.styleSheets[0].cssRules[5].cssRules[0].style.backgroundColor = getComputedStyle(a).backgroundColor;
document.writeln(getComputedStyle(a).backgroundColor);
document.writeln(getComputedStyle(b).backgroundColor);
document.writeln(getComputedStyle(c).backgroundColor);
</script>

The background of #a is the interpolation between rgb(75, 0, 0) and rgb(0, 255, 0). The easing function is linear(0, -1, 1), so at 50% the input progress value is -1. Both colors are legacy, so we interpolate in srgb instead of oklab, producing a color as such:

  • Color space: srgb
  • Legacy flag: yes
  • Red: 150
  • Green: -255
  • Blue: 0

But of course, G = -255 is out of bounds, so the painted background is rgb(150, 0, 0).

However, on Gecko and Blink, the computed value still has this G = -255, as we can observe in #b. The background color of #b is the 50% linear interpolation between the value inherited from #a and rgb(0, 255, 0). This serializes as rgb(75, 0, 0), which means that the inherited value has G = -255.

The problem is, what do we get if we serialize the computed value of #a? Since G = -255 is out-of-bounds, browsers just clamp and serialize as rgb(150, 0, 0).

But of course, when #c does the same as #b, but interpolating from the provided rgb(150, 0, 0), then it produces rgb(75, 128, 0).

WebKit seems to adjust the computed value of #a, because #b produces rgb(75, 128, 0) just like #c.

So, questions:

  • Why does color-mix() prevent me from picking a percentage outside of the 0-100% range, if I can do the mix with arbitrary values via animations/transitions (but it's much less convenient)?
  • Should Gecko and Blink adjust the computed value to avoid out-of-bounds problems?
  • If not, should we change the serialization so that it doesn't become a different color? Maybe serialize with color-mix()?
@Loirooriol Loirooriol added css-color-4 Current Work css-color-5 Color modification labels Mar 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-color-4 Current Work css-color-5 Color modification
Projects
None yet
Development

No branches or pull requests

2 participants
@Loirooriol and others