Geht wählen! Am 26. September 2021 ist Bundestagswahl in Deutschland, wählt Annalena Baerbock für zukunftssichere Klima-, Digital- und Sozialpolitik.. Mehr infos zum Wahlprogramm auf gruene.de 🗳💚🌻

Darken and Lighten colors with CSS

Recreating SASS darken() & lighten() function with CSS variables and calc

Written by Kevin Gimbel on , 🍿 4 min. read

The technique shown in this post uses the hsl color format in combination with the calc CSS function to calculate darker or lighter shades of a base color.

Before we get into the code I want to make sure I did not come up with this, I found the code on StackOverflow and only want to write about it to keep it on my site for future reference! :)

The code

:root {
--color: 0, 100%;
--l:50%;

--color-primary: hsl(var(--color),var(--l));
--color-primary-darker: hsl(var(--color),calc(var(--l) - 10%));
--color-primary-darkest: hsl(var(--color),calc(var(--l) - 30%));
}

Here we define a color variable named --color that holds the first two values of a hsl color definition: The hue and saturation value. The third value, lightness is calculated based on the default lightness value (--l).

The HSL color function takes three values:

  • H is the hue, a number from 0 to 360
  • S is the saturation, in percent 0 to 100
  • L is the lightness, in percent from 0 to 100

The lightness can be increased to make the color lighter and decreased to make it darker.

The result

See the Pen Unknown Pen on CodePen.

We can also apply the variables on a class level instead of the :root element so they are calculated every time the class is used, which enables "theming", as the following CodePen shows.

The green and blue class set different values for --color, therefore changing the values of --color-primary, --color-primary-darker, and --color-primary-darkest.

See the Pen Unknown Pen on CodePen.

Below is the new CSS code.

:root {
--color: 0, 100%;
--l:50%; /*the initial lightness*/
}

.darken {
--color-primary: hsl(var(--color),var(--l));
--color-primary-darker: hsl(var(--color),calc(var(--l) - 10%));
--color-primary-darkest: hsl(var(--color),calc(var(--l) - 30%));

color: var(--color-primary-darkest);
background: var(--color-primary);
}

.green {
--color:120, 50%;
}

.blue {
--color:245, 60%;
--l: 80%;
}

lighten

The lighten function works in the same way, just that it would increase the lightness instead of decreasing it.

.lighten {
--color: 0, 100%;
--l:50%;

--color-primary: hsl(var(--color),var(--l));
--color-primary-lighter: hsl(var(--color),calc(var(--l) + 10%));
--color-primary-lightest: hsl(var(--color),calc(var(--l) + 30%));
}

Browser Support

Just for completeness, here's the Browser support. It's looking pretty good with over 90% for both features used (as of June 2021).

Data on support for the calc feature across the major browsers from caniuse.com

Data on support for the css-variables feature across the major browsers from caniuse.com

Further reading

Hi, I'm Kevin!

I'm a DevOps Engineer with a focus on automation and security. Before shifting into DevOps and cloud computing I worked as Front-End Developer, which is still a hobby and field of interest for me.

Hand-made vector avatar of Kevin Gimbel

I'm very passionated about a variety of games - digital, boardgames, and pen & paper; and also interested in Sci-Fi, Cyberpunk, and dystopian books. You can find out more on the about page.