CSS: Why does converting a hex color to hsl and then back to hex lead to a different value
Asked Answered
N

1

6

Strange thing that I discovered. When converting #579f2f to hsl, I arrive at hsl(99, 54%, 40%);. When converting this back to hex I get #559d2f. I used various online tools to test this.

I guess the reason is that hsl describes the colors as hue (0-360), saturation (0-100%) and lightness (0-100%) and hex is just RGB (0-255,0-255,0-255) written as three hexadecimal numbers, so the color space hsl describes (or the amount of colors you can possibly express) is different.

RGB: 255^3 = 16,581,375 colors
HSL: 360*100*100 = 3,600,000 colors

Am I right in this assumption or is there a different reason?

Normie answered 5/9, 2019 at 11:15 Comment(9)
The actual HSL for #579f2f would be hsl(98.6, 54.4%, 40.4%) so I'd say it's because of the rounding. Try it here: convertacolor.comKeck
This is because of rounding the hsl values to int's. And, yes you can cpver more colors with int hsl colors than with int rgb colors.Zorn
@Keck because of rounding. Of course. Issue is only that I have to round for CSS.Normie
@Zorn How can hsl cover more colors than rgb? If you only look at the potential outputs of the functions hsl(360,100,100) and rgb(255,255,255), then the amount of values you can express is much larger for rgb.Normie
BTW rgb (at 8 bits) has 256^3, but please try not to assume 8bit values, and BTW in hsl, all values with S=0 or L=0 describe the same colour.Delative
PS: do not worry, we cannot see more then 3 millions of colour, for sure not on most computer screens.Delative
@OleSpaarmann Oops! I mixed it up, sorry. Using int rgb and hsl gives you more css colors in rgb space for sure.Zorn
@OleSpaarmann for me it works with decimals in HSL jsfiddle.net/n2azqx9f/1 Does it not work for you?Keck
@Keck I have no idea why it did not work for me. It does indeed work. Strange. Thanks for pointing it out again!Normie
S
5

Technically, hsl notation can be used with <number> and not only integer. This make the possible colors more than what you already calculated and can cover all the rgb ones

$('.box').each(function() {
  console.log($(this).css('background-color'));
});
.box {
 height:40px;
 margin:10px;
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box" style="background-color:hsl(12deg,11%,51%)"></div>
<div class="box" style="background-color:hsl(11.9deg,10.9%,50.9%)"></div>
<div class="box" style="background-color:hsl(11.1deg,10.9%,50.5%)"></div>
<div class="box" style="background-color:hsl(11.1deg,10.1%,50.5%)"></div>
<div class="box" style="background-color:hsl(11.1deg,10.1%,50.1%)"></div>
<div class="box" style="background-color:hsl(11deg,10%,50%)"></div>

Note that the angle can be expressed using rad and turn. A uniteless value is by default considered a deg. If degree is bettwen 0 and 360, turn is only between 0 and 1 and radians is between 0 and PI (3.14)ref

$('.box').each(function() {
  console.log($(this).css('background-color'));
});
.box {
 height:40px;
 margin:10px;
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box" style="background-color:hsl(1.12rad,11%,51%)"></div>
<div class="box" style="background-color:hsl(1.125rad,10.9%,50.9%)"></div>
<div class="box" style="background-color:hsl(1.125rad,10.9%,50.5%)"></div>
<div class="box" style="background-color:hsl(1.13rad,10.1%,50.5%)"></div>
<div class="box" style="background-color:hsl(1.134rad,10.1%,50.1%)"></div>
<div class="box" style="background-color:hsl(1.132rad,10%,50%)"></div>
Stilla answered 5/9, 2019 at 11:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.