- From: Andreas Linnert via GitHub <noreply@w3.org>
- Date: Sun, 17 May 2026 23:52:55 +0000
- To: public-css-archive@w3.org
alinnert has just created a new issue for https://github.com/w3c/csswg-drafts:
== [css-color-5] [css-values] Using color components in trigonometric functions in relative color syntax yield different results in different browsers ==
## Problem
If you use a color component value (like `h`, `s`, or `l`) inside a trigonometric function (like `sin()` or `cos()`) inside the relative color syntax the result differs in every major browser.
I found there seem to be no WPT tests that check for this specific combination of CSS features.
### Example
``` css
.element {
background: hsl(from hsl(0 50 50) h s calc((sin(l) + 1) * 50));
}
```
I've also created [a JSFiddle](https://jsfiddle.net/alinnert/4o0gwzby/) to demonstrate the issue.
## What the specs say
[The spec of the relative color syntax](https://drafts.csswg.org/css-color-5/#relative-syntax) says:
> The [component keywords](https://drafts.csswg.org/css-color-5/#component-keyword) return a [\<number>](https://drafts.csswg.org/css-values-4/#number-value), or [none](https://drafts.csswg.org/css-color-5/#valdef-light-dark-none); if they were originally specified as a [\<percentage>](https://drafts.csswg.org/css-values-4/#percentage-value) or an [\<angle>](https://drafts.csswg.org/css-values-4/#angle-value), that \<percentage> is resolved to a \<number> and the \<angle> is resolved to a \<number> of degrees (which is the [canonical unit](https://drafts.csswg.org/css-values-4/#canonical-unit)) in the range [0, 360].
[The spec of the Trigonometric Functions](https://drafts.csswg.org/css-values/#trig-funcs) says:
> The sin(A), cos(A), and tan(A) functions all contain a single [calculation](https://drafts.csswg.org/css-values/#calc-calculation) which must resolve to either a [\<number>](https://drafts.csswg.org/css-values/#number-value) or an [\<angle>](https://drafts.csswg.org/css-values/#angle-value), and compute their corresponding function by interpreting the result of their argument as radians. (That is, sin(45deg), sin(.125turn), and sin(3.14159 / 4) all represent the same value, approximately .707.)
## Expected behavior
A lightness value of `50` (or `50%`) in the origin-color should resolve to the \<number> `50`. This means that `sin(l)` and `sin(50)` should be equivalent. In both cases it should be interpreted as `sin(50rad)` which yields the value `-0.2623748537`. By adding `1` and multiplying the value with `100` you get a value between `0` and `100` - in this case `36.8812573148`. That means the final color should be `hsl(0 50 36.8812573148)`.
## Actual behavior
### Safari 26.5
Safari actually produces the correct color.
<details>
<summary>Safari screenshot</summary>
<img width="2630" height="1708" alt="Image" src="https://github.com/user-attachments/assets/b319d800-b120-4c4f-a33d-62a0db8109f4" />
</details>
### Chrome 148.0.7778.168
Chrome produces a different color: `hsl(0 49.8 88.3)`
After trying a few different values it seems that Chrome interprets `50%` as `50deg` when used in `sin()`. So, it calculates `sin(50deg)` instead of `sin(50rad)`. I think so because:
- A lightness value of `0` in the origin-color produces a color with medium brightness
- A value of `90` produces the lightest color
- A value of `180` produces the same color as the value `0`
- A value of `270` produces the darkest color
- A value of `360` produces the same color as the value `0`
I've checked all values from `0` to `360` in steps of `10` to be sure.
<details>
<summary>Chrome screenshot</summary>
<img width="2630" height="1708" alt="Image" src="https://github.com/user-attachments/assets/46f75ab5-cd9d-4a81-b7c2-2878938e1d7a" />
</details>
### Firefox 150.0.3
Firefox cannot calculate any color doing that. So, some form of internal error seems to occur. But the exact result depends on what the origin-color actually is.
Assuming I'm using a fallback color like this:
``` css
.element {
background: gray;
background: hsl(from hsl(0 50 50) h s calc((sin(l) + 1) * 50));
}
```
- If the origin-color is `currentColor` (`hsl(from currentColor ...)`) or a color function (like above) then the fallback color gets used.
- If the origin-color is a custom property however (`hsl(from var(--some-color) ...)`) no color is used at all and the element gets rendered with a transparent background, ignoring all `background` rules all together.
<details>
<summary>Firefox screenshot</summary>
- The orange box (with the diagonal line from bottom left to top right) represents the case where the fallback color gets ignored and the target element gets rendered with a transparent background.
- The red boxes (with the diagonal line from top left to bottom right) represent the case where the fallback color gets used.
<img width="2630" height="1708" alt="Image" src="https://github.com/user-attachments/assets/72a42604-e30f-4d55-bf97-3d680fd8c738" />
</details>
## What was I trying to do?
I was trying to make any color darker in a way so that light colors get way more dark than colors that are already somewhat dark. That's why I came up with this formula:
``` css
.element {
background: hsl(from currentColor h s calc((sin((l * pi) / 200) * 100) / 2));
}
```
If it worked correctly it would result in every color having a lightness value between `0` and `50` while dark colors would be brighter than they would be with `calc(l / 2)`.
Here's a graph to visualize that:
<details>
<summary>Show graph</summary>
- The black, straight graph represents `calc(l / 2)`
- The red, curved graph represents `calc((sin((l * pi) / 200) * 100) / 2))`
<img width="2546" height="1706" alt="Image" src="https://github.com/user-attachments/assets/836accb6-da1d-4039-a12c-7c3c9ad9ca06" />
</details>
## Next steps, questions
I wanted to make sure that my version of "expected behavior" is correct. If that's the case I try to open issues on Firefox' and Chrome's issue tracker as well as create WPT tests.
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/13938 using your GitHub account
--
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Sunday, 17 May 2026 23:52:56 UTC