
When writing CSS, the commonest codecs we use for expressing a coloration are both a hex code like#BADA55 or an RGB worth likergb(125, 130, 110). Design instruments like Sketch or Figma usually use these codecs as their default.
Nonetheless, there are different codecs, resembling HSL.
To cite MDN:
The hsl() purposeful notation expresses a coloration within the sRGB coloration house in line with its hue, saturation, and lightness elements.
Seeing coloration like an artist
Chances are you’ll be asking your self why we’d need one thing totally different if the hex and RGB codecs are primarily ubiquitous.
One purpose is that HSL fashions coloration in three dimensions, and these dimensions make a variety of sense to our notion of coloration as people.
Let’s take the hex code#BADA55. Simply by glancing at it, do you could have any thought what the precise coloration is? In the event you’ve been a front-end developer for so long as I’ve, you would possibly know this one. However what if I modify the code to#12DA55? How is the colour affected?
What aboutrgb(12, 134, 200)? We all know that RGB stands for purple, inexperienced, and blue, so we are able to infer that the ensuing coloration is a mix of these values. If theb is de facto excessive in comparison with ther andg, 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 will not be intuitive for us. In any case, we have been taught that blue + yellow = inexperienced — and there’s no yellow in RGB! Nicely, technically there’s, however even then, mixing mild colours will not be the identical as mixing paint colours.
Think about that you just wished a barely darker model of those colours; how are you going to 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: purple, blue, orange, and so forth. Folks usually describe coloration by referencing its hue. The hue worth is represented by its place on a “coloration 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 purple. The size goes from 0% (gray) to 100% (pure coloration).
Lightness: This worth determines whether or not a coloration is mild or darkish, with the size starting from 0% mild (black) to 100% mild (white).
With these definitions below our belt, let’s take some values and see what can we infer about them earlier than seeing the colour they signify:
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 it is a fully gray coloration proper in the course of the lightness scale. Actually, 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 can keep white.
One other factor to find out about HSL is that it accepts an additional argument for an alpha worth, which determines how clear the colour must be. Identical to with thea inrgba, the syntax appears to be like like this:hsl(75, 67%, 70% / 25%).
Now you could see how intuitive it’s to make sense of a coloration utilizing this format, let’s determine a fast option to darken a coloration a bit bit utilizinghsl.
Ranging from a base coloration likehsl(75, 67%, 63%), all we have to do is modify the lightness worth: hsl(75, 67%, 40%). Bear in mind, the decrease the lightness worth, the darker the ensuing coloration will likely be.
Whereas understanding HSL is easy, I’d be remiss if I didn’t point out that coloration, usually, 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. Which means simply because a coloration’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 worthhsl(200, 100%, 84%), a blue coloration. Saturation is at 100% right here, however on the similar time we’ve a really excessive lightness worth, so the ensuing coloration will not be as intense or brilliant as that specific 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 lowering the depth of the colour. This up and down “wave” of depth varies by hue.
Shade concept 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 coloration. Whereas that system is designed for pigments and never mild (as in screens), it nonetheless illustrates nicely what I am describing:
Every chart is a distinct 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 potential 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 follow.
HSL + CSS properties = energy
All the pieces we’ve talked about to date is attention-grabbing, however apart from the admittedly cool advantage of figuring out what a coloration would possibly appear 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 situation the place hsl would possibly truly come in 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:
#ace3ffpurple:
#ddccffinexperienced:
#bcf1ca
On hover, a tag background coloration ought to get a bit darker (values not offered).
First, let’s get out of the way in which what might be the obvious answer: simply use JavaScript! In the event you’re considering that there have to be dozens of libraries that may do that for you, you’re appropriate:
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 answer signifies that we had so as to add an additional dependency only for this very particular use case.
May we presumably consider a option to obtain this and not using a third-party library and, even higher, achieve this 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:
perform Tag(props) {
const { coloration, textual content } = props
return <button className={`Tag ${coloration}`}>{textual content}</button>
}Our new part could be very easy, and it takes two props: the textual content of the tag and a coloration from a predetermined set (‘blue’, ‘purple’ and ‘inexperienced’).
We add an additional class identify on thebutton to deal with the colour with CSS. If the colour worth handed will not be discovered on the set, the Tag will get a gray coloration.
Let’s type that a bit bit, dealing with the colours:
.Tag {
show: inline-block;
peak: 16px;
padding: 0 8px;
border-radius: 3px;
line-peak: 16px;
font-dimension: 12px;
coloration: #314351;
background-coloration: var(--tag-background-coloration);
border: 0;
coloration: #314351;
background-coloration: #c8d3de;
}
.Tag.blue {
background-coloration: #ace3ff;
}
.Tag.purple {
background-coloration: #ddccff;
}
.Tag.inexperienced {
background-coloration: #bcf1ca;
}To this point so good! Let’s refactor that by changing values to HSL and utilizing CSS variables:
.Tag {
--tag-background-coloration: hsl(210, 25%, 83%);
coloration: #314351;
background-coloration: var(--tag-background-coloration);
}
.Tag.blue {
--tag-background-coloration: hsl(200, 100%, 84%);
}
.Tag.purple {
--tag-background-coloration: hsl(260, 100%, 90%);
}
.Tag.inexperienced {
--tag-background-coloration: hsl(136, 65%, 84%);
}Discover how simply by trying on the hsl values we are able to quickly inform that these are very mild 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 conduct. We all know that we have to decrease the lightness worth to attain a darker coloration with the identical hue and saturation. To attain that, it will likely be helpful to interrupt down ourhsl values into their particular person models:
.Tag {
--tag-background-coloration-h: 210;
--tag-background-coloration-s: 25%;
--tag-background-coloration-l: 83%;
--tag-background-coloration: hsl(
var(--tag-background-coloration-h)
var(--tag-background-coloration-s)
var(--tag-background-coloration-l)
);
background-coloration: var(--tag-background-coloration);
}
.Tag.blue {
--tag-background-coloration-h: 200;
--tag-background-coloration-s: 100%;
--tag-background-coloration-l: 84%;
}
.Tag.purple {
--tag-background-coloration-h: 260;
--tag-background-coloration-s: 100%;
--tag-background-coloration-l: 90%;
}
.Tag.inexperienced {
--tag-background-coloration-h: 136;
--tag-background-coloration-s: 65%;
--tag-background-coloration-l: 84%;
}To this point, we’ve not modified a lot, however discover how the CSShsl perform accepts CSS variables.
Lastly, for the hover impact, let’s scale back every coloration lightness worth by 10%. To maintain the instance brief, we’ll simply listing one of many colours:
.Tag {
--tag-background-coloration-h: 210;
--tag-background-coloration-s: 25%;
--tag-background-coloration-l: 83%;
--tag-background-coloration: hsl(
var(--tag-background-coloration-h)
var(--tag-background-coloration-s)
var(--tag-background-coloration-l)
);
background-coloration: var(--tag-background-coloration);
}
.Tag:hover {
--tag-background-coloration-l: 73%;
}
.Tag.blue {
--tag-background-coloration-h: 200;
--tag-background-coloration-s: 100%;
--tag-background-coloration-l: 84%;
}
.Tag.blue:hover {
--tag-background-coloration-l: 74%;
}Earlier than ending up, let’s enhance the instance a bit. We wish to:
Eradicate some repetition, which may also enable us to simply add extra Tag colours sooner or later.
Roughly think about what we discovered about saturation ranges from the colour concept defined earlier within the put up.
The complete instance might look one thing like this:
.Tag {
--tag-background-coloration-h: 210;
--tag-background-coloration-s: 25%;
--tag-background-coloration-l: 83%;
--tag-background-coloration: hsl(
var(--tag-background-coloration-h)
var(--tag-background-coloration-s)
var(--tag-background-coloration-l)
);
--tag-background-coloration-darker: hsl(
var(--tag-background-coloration-h)
calc(var(--tag-background-coloration-s) - 20%)
calc(var(--tag-background-coloration-l) - 10%)
);
show: inline-block;
peak: 16px;
padding: 0 8px;
border-radius: 3px;
line-peak: 16px;
font-dimension: 12px;
coloration: #314351;
border: 0;
background-coloration: var(--tag-background-coloration);
}
.Tag.blue {
--tag-background-coloration-h: 200;
--tag-background-coloration-s: 100%;
--tag-background-coloration-l: 84%;
}
.Tag.purple {
--tag-background-coloration-h: 260;
--tag-background-coloration-s: 100%;
--tag-background-coloration-l: 90%;
}
.Tag.inexperienced {
--tag-background-coloration-h: 136;
--tag-background-coloration-s: 65%;
--tag-background-coloration-l: 84%;
}
.Tag.yellow {
--tag-background-coloration-h: 50;
--tag-background-coloration-s: 100%;
--tag-background-coloration-l: 67%;
}
.Tag:hover {
background-coloration: var(--tag-background-coloration-darker);
}The outcomes
The distinction is delicate and whether or not it appears to be like higher or not is subjective, however the objective right here is to point out you that it is potential to govern these values in inventive methods with simply CSS.
Earlier than:
After:
Hopefully you discovered this dialogue of coloration concept and HSL attention-grabbing and that it conjures up you in your future tasks!

