When writing CSS, the commonest codecs we use for expressing a colour are both a hex code like #BADA55
or an RGB worth like rgb(125,130,110)
. Design instruments like Sketch or Figma typically use these codecs as their default.
Nevertheless, there are different codecs, comparable to HSL.
To cite MDN:
The hsl() practical notation expresses a colour within the sRGBcolour area based on its hue, saturation, and lightness elements.
Seeing colour like an artist
You could be asking your self why we might need one thing totally different if the hex and RGB codecs are basically ubiquitous.
One cause is that HSL fashions colour in three dimensions, and these dimensions make plenty of sense to our notion of colour as people.
Let’s take the hex code #BADA55
. Simply by glancing at it, do you may have any thought what the precise colour is? When you’ve been a front-end developer for so long as I’ve, you may know this one. However what if I alter the code to #12DA55
? How is the colour affected?
What about rgb(12,134,200)
? We all know that RGB stands for pink, inexperienced, and blue, so we are able to infer that the ensuing colour is a mix of these values. If the b
is admittedly excessive in comparison with the r
and g
, we are able to guess the colour is on the blue facet of the spectrum, however how would you get an orange or a yellow from mixing these values?
The way in which RGB values are blended isn’t intuitive for us. In any case, we have been taught that blue + yellow = inexperienced — and there’s no yellow in RGB! Effectively, technically there may be, however even then, mixing gentle colours isn’t the identical as mixing paint colours.
Think about that you simply wished a barely darker model of those colours; how will you get them with out firing up Photoshop?
Enter HSL. Let’s check out what every letter stands for:
Hue: Consider this worth because the identify of the colour: pink, blue, orange, and many others. Individuals usually describe colour by referencing its hue. The hue worth is represented by its place on a “colour wheel,” from 0 to 360 levels.
Saturation: This worth tells us how intense the colour is, from a uninteresting gray to a burn-your-retina hearth engine pink. The size goes from 0% (gray) to 100% (pure colour).
Lightness: This worth determines whether or not a colour is gentle or darkish, with the dimensions starting from 0% gentle (black) to 100% gentle (white).
With these definitions underneath our belt, let’s take some values and see what can we infer about them earlier than seeing the colour they symbolize:
-
h: 45deg,s:0%,l:50%
With out figuring out the values of the hue wheel, we are able to instantly inform by the opposite values that this can be a fully gray colour proper in the midst of the lightness scale. In reality, it would not matter how a lot we modify the hue worth, the truth that the saturation is 0%, makes it a impartial gray. -
h: 93deg,s:75%,l:100%
The identical logic applies right here. We would don’t know what the hue is, however we are able to inform by the lightness worth of 100% that it’s white. On this case, it would not matter what values we give the hue or the saturation, it would keep white.
One other factor to learn about HSL is that it accepts an additional argument for an alpha worth, which determines how clear the colour must be. Identical to with the a
in rgba
, the syntax appears like this: hsl(75,67%,70%/25%)
.
Now you can see how intuitive it’s to make sense of a colour utilizing this format, let’s determine a fast method to darken a colour slightly bit utilizing hsl
.
Ranging from a base colour like hsl(75,67%,63%)
, all we have to do is modify the lightness worth: hsl(75,67%,40%)
. Keep in mind, the decrease the lightness worth, the darker the ensuing colour shall be.
Whereas understanding HSL is straightforward, I’d be remiss if I didn’t point out that colour, generally, is a fancy topic. For instance, every hue’s saturation peaks at totally different lightness values as a result of some hues are naturally darker than others, like yellow vs. blue. Because of this simply because a colour’s saturation is at 100%, it doesn’t imply that the colour is at its peak depth; the lightness worth nonetheless has an impact on it.
Let’s take the worth hsl(200,100%,84%)
, a blue colour. Saturation is at 100% right here, however on the similar time we now have a really excessive lightness worth, so the ensuing colour isn’t as intense or vivid as that exact hue might be. If we decrease the lightness worth, we’ll begin rising the perceived depth of the hue till it peaks. As soon as we attain that peak degree, making it darker will begin reducing the depth of the colour. This up and down “wave” of depth varies by hue.
Shade idea is a really attention-grabbing and huge topic, one I am unable to get into too deeply on this article. Nonetheless, take a look at these charts from the Munsell system of colour. Whereas that system is designed for pigments and never gentle (as in screens), it nonetheless illustrates nicely what I am describing:
Every chart is a special hue. Munsell makes use of the phrases hue, worth (as a substitute of lightness), and chroma (as a substitute of saturation).
From prime to backside, we go from excessive to low lightness with out reaching black or white, which might be the identical for every hue.
From left to proper we go from low saturation (nearly impartial gray) to the very best attainable saturation for every hue.
Discover how yellow’s saturation peaks on the highest lightness worth (9/12) and blue extra within the center (6/14).
OK, let’s transfer on and see how one can put your new information of HSL into observe.
HSL + CSS properties = energy
All the pieces we’ve talked about up to now is attention-grabbing, however aside from the admittedly cool good thing about figuring out what a colour may seem like simply by glancing at a hsl worth and with the ability to rapidly modify it, it is not that a lot totally different from our good outdated mates, hex and RGB.
Let’s consider an actual state of affairs the place hsl may truly turn out to be useful and permit us to do issues the opposite codecs can’t simply do.
Say we’re constructing a “Tag” part, and amongst its necessities, we see these listed:
They need to be buttons.
There are three background colours obtainable for our tags.
blue:
#ace3ff
purple:
#ddccff
inexperienced:
#bcf1ca
On hover, a tag background colour ought to get slightly darker (values not supplied).
First, let’s get out of the way in which what might be the obvious resolution: simply use JavaScript! When you’re pondering that there should be dozens of libraries that may do that for you, you might be right:
import chroma from"chroma-js";
const color1 ='#D4F880'
const color1Hover =chroma(color1).darken(1).hex();
However the place is the enjoyable in that?! Plus, this resolution signifies that we had so as to add an additional dependency only for this very particular use case.
May we probably consider a method to obtain this and not using a third-party library and, even higher, accomplish that whereas solely utilizing CSS?
To begin, let’s outline a quite simple Tag part. To simplify the examples, we’re going to use React syntax, however very calmly, so this may be ported to something from “vanilla” to Vue or no matter you like:
operateTag(props){
const{ colour, textual content }=
props
return<button className={`Tag ${colour}`}>{textual content}</button>
}
Our new part could be very easy, and it takes two props: the textual content of the tag and a colour from a predetermined set (‘blue’, ‘purple’ and ‘inexperienced’).
We add an additional class identify on the button
to deal with the colour with CSS. If the colour worth handed isn’t discovered on the set, the Tag will get a gray colour.
Let’s fashion that slightly bit, dealing with the colours:
.Tag {
show: inline-block;
top: 16px;
padding:0 8px;
border-radius: 3px;
line-top: 16px;
font-dimension: 12px;
colour: #314351;
background-colour:var(--tag-background-colour);
border:0;
colour: #314351;
background-colour: #c8d3de;
}
.Tag.blue {
background-colour: #ace3ff;
}
.Tag.purple {
background-colour: #ddccff;
}
.Tag.inexperienced {
background-colour: #bcf1ca;
}
To this point so good! Let’s refactor that by changing values to HSL and utilizing CSS variables:
.Tag {
--tag-background-colour:hsl(210,25%,83%);
colour: #314351;
background-colour:var(--tag-background-colour);
}
.Tag.blue {
--tag-background-colour:hsl(200,100%,84%);
}
.Tag.purple {
--tag-background-colour:hsl(260,100%,90%);
}
.Tag.inexperienced {
--tag-background-colour:hsl(136,65%,84%);
}
Discover how simply by trying on the hsl values we are able to quickly inform that these are very gentle colours. Within the case of the blue and purple, the saturation is at 100%, which implies they’re as colourful as they are often at that degree of lightness.
Time to implement the hover habits. We all know that we have to decrease the lightness worth to realize a darker colour with the identical hue and saturation. To attain that, it is going to be helpful to interrupt down our hsl
values into their particular person models:
.Tag {
--tag-background-colour-h:210;
--tag-background-colour-s:25%;
--tag-background-colour-l:83%;
--tag-background-colour:hsl(
var(--tag-background-colour-h)
var(--tag-background-colour-s)
var(--tag-background-colour-l)
);
background-colour:var(--tag-background-colour);
}
.Tag.blue {
--tag-background-colour-h:200;
--tag-background-colour-s:100%;
--tag-background-colour-l:84%;
}
.Tag.purple {
--tag-background-colour-h:260;
--tag-background-colour-s:100%;
--tag-background-colour-l:90%;
}
.Tag.inexperienced {
--tag-background-colour-h:136;
--tag-background-colour-s:65%;
--tag-background-colour-l:84%;
}
To this point, we’ve not modified a lot, however discover how the CSS hsl
operate accepts CSS variables.
Lastly, for the hover impact, let’s cut back every colour lightness worth by 10%. To maintain the instance quick, we’ll simply listing one of many colours:
.Tag {
--tag-background-colour-h:210;
--tag-background-colour-s:25%;
--tag-background-colour-l:83%;
--tag-background-colour:hsl(
var(--tag-background-colour-h)
var(--tag-background-colour-s)
var(--tag-background-colour-l)
);
background-colour:var(--tag-background-colour);
}
.Tag:hover {
--tag-background-colour-l:73%;
}
.Tag.blue {
--tag-background-colour-h:200;
--tag-background-colour-s:100%;
--tag-background-colour-l:84%;
}
.Tag.blue:hover {
--tag-background-colour-l:74%;
}
Earlier than ending up, let’s enhance the instance a bit. We want to:
Remove some repetition, which will even enable us to simply add extra Tag colours sooner or later.
Roughly think about what we discovered about saturation ranges from the colour idea defined earlier within the publish.
The complete instance might look one thing like this:
.Tag {
--tag-background-colour-h:210;
--tag-background-colour-s:25%;
--tag-background-colour-l:83%;
--tag-background-colour:hsl(
var(--tag-background-colour-h)
var(--tag-background-colour-s)
var(--tag-background-colour-l)
);
--tag-background-colour-darker:hsl(
var(--tag-background-colour-h)
calc(var(--tag-background-colour-s)-20%)
calc(var(--tag-background-colour-l)-10%)
);
show: inline-block;
top: 16px;
padding:0 8px;
border-radius: 3px;
line-top: 16px;
font-dimension: 12px;
colour: #314351;
border:0;
background-colour:var(--tag-background-colour);
}
.Tag.blue {
--tag-background-colour-h:200;
--tag-background-colour-s:100%;
--tag-background-colour-l:84%;
}
.Tag.purple {
--tag-background-colour-h:260;
--tag-background-colour-s:100%;
--tag-background-colour-l:90%;
}
.Tag.inexperienced {
--tag-background-colour-h:136;
--tag-background-colour-s:65%;
--tag-background-colour-l:84%;
}
.Tag.yellow {
--tag-background-colour-h:50;
--tag-background-colour-s:100%;
--tag-background-colour-l:67%;
}
.Tag:hover {
background-colour:var(--tag-background-colour-darker);
}
The outcomes
The distinction is refined and whether or not it appears higher or not is subjective, however the purpose right here is to point out you that it is attainable to govern these values in inventive methods with simply CSS.
Earlier than:
After:
Hopefully you discovered this dialogue of colour idea and HSL attention-grabbing and that it evokes you in your future initiatives!