- From: Oriol Brufau via GitHub <sysbot+gh@w3.org>
- Date: Thu, 14 Mar 2024 20:28:41 +0000
- To: public-css-archive@w3.org
Loirooriol has just created a new issue for https://github.com/w3c/csswg-drafts:
== [css-color] How to handle out-of-bounds legacy srgb values? ==
Consider this testcase:
```html
<!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: black }
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()`?
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/10087 using your GitHub account
--
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Thursday, 14 March 2024 20:28:42 UTC