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

possible rounding error when converting hsl to hex #1909

Closed
matovas opened this issue Nov 23, 2015 · 7 comments

Comments

@matovas
Copy link

@matovas matovas commented Nov 23, 2015

Sass automaticaly converted hsl to #hex colors.
Some times this process has small bug.

// styles.scss
$pink_5l: hsl(340, 80%, 95%);
body { background-color: $pink_5l; }

// styles.css
body { background-color: #fce8ef; }

All good, but hsl(340, 80%, 95%) ≠ #fce8ef,
because #fce8ef = hsl(339, 77%, 95%)

I testing this, my result
hsl(340, 80%, 95%) — bad converting
hsl(340, 80%, 90%) — good converting
hsl(340, 80%, 80%) — good converting
hsl(340, 80%, 70%) — good converting
hsl(340, 80%, 60%) — good converting
hsl(340, 80%, 50%) — good converting
hsl(340, 80%, 40%) — good converting
hsl(340, 80%, 30%) — good converting
hsl(340, 80%, 20%) — good converting
hsl(340, 80%, 10%) — good converting
hsl(340, 80%, 5%) — bad converting

Thanks!

@cimmanon

This comment has been minimized.

Copy link

@cimmanon cimmanon commented Mar 17, 2016

If you write in hsl(340, 80%, 95%) using Chrome's inspector, you can see how it is interpreted in other formats. It thinks that color is equal to #fce8ef. But if you fill out the hex value instead, you get hsl(339, 77%, 95%). Sass is not wrong here. Two different sets of HSL values can be equal to the same RGB value.

What values are you expecting for those other colors?

@chriseppstein

This comment has been minimized.

Copy link
Member

@chriseppstein chriseppstein commented Mar 17, 2016

It's true that both of these colors map to the same value in RGB, but if you look here at this example, you will see that there is a visual distinction (albeit very minor) between the two when specified in hsl. As such, I think we need to consider this a bug.

http://codepen.io/chriseppstein/full/PNWQRg/

It's not a simple fix. There are browser support concerns. We may need to add a work around via the upcoming to-css() function in the near term.

@cimmanon

This comment has been minimized.

Copy link

@cimmanon cimmanon commented Mar 17, 2016

I don't know if this is worth mentioning or not, but Chrome's inspector says that hsl(30, 100%, 50%) is equivalent to rgb(255, 127, 0). Meanwhile writing in rgb(255, 128, 0) results in hsl(30, 100%, 50%). I've been over the formula provided by the W3C hundreds of times and the G channel in this case comes back as 127.5. I don't know how this value is rounding down to 127 unless it is supposed to be floored (but wouldn't that make all of the other colors off as well?).

Sass reports hsl(30, 100%, 50%) as being equivalent to rgb(255, 128, 0).

@chriseppstein

This comment has been minimized.

Copy link
Member

@chriseppstein chriseppstein commented Mar 17, 2016

@tabatkins are there colors expressible in hsl() that the browser will display that cannot be expressed in rgb? Trying to decide if this is a fundamental flaw in Sass's treatment of hsl or just a small bug in our hsl -> rgb algorithm.

@tabatkins

This comment has been minimized.

Copy link

@tabatkins tabatkins commented Mar 17, 2016

No, HSL and RGB are equivalent color-spaces. This is just a matter of different rounding/floating-point error accumulation between implementations.

(And at extreme light/dark values, the color-space is very small - those are the corners of the RGB cube, so not much left to discriminate. There's a lot of quantization going on there, so in general values won't round-trip exactly. A good implementation will at least make sure that converting back and forth matches what you get if you convert back and forth twice, but it's easy to write something that doesn't quite do that, and introduces a little bit of drift into the extreme values. Similarly, at very low saturation a round-trip will often drift your hue.)

@chriseppstein

This comment has been minimized.

Copy link
Member

@chriseppstein chriseppstein commented Mar 17, 2016

@chriseppstein chriseppstein changed the title autoconverting hsl() to #hex possible rounding error when converting hsl to hex Mar 17, 2016
@nex3 nex3 removed their assignment May 20, 2016
@nex3

This comment has been minimized.

Copy link
Contributor

@nex3 nex3 commented Apr 6, 2018

I'm closing this out. I don't think it's feasible to guarantee that this translation round-trips identically, given that multiple HSL colors translate to the same RGB color.

@nex3 nex3 closed this Apr 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.