How to create color shades using CSS variables similar to darken() of SASS?

Daniel picture Daniel · Mar 25, 2019 · Viewed 14.5k times · Source

I'm looking a way of modifying a CSS variable as you would in SCSS

Define a color like primary - and automatically I would get shades for focus and actives states. Basically, would like to change one variable in css variables and get 3 shades of the same color.

What Id like to achieve in CSS

$color-primary: #f00;

.button {
    background: $color-primary;

    &:hover,
    &:focus {
        background: darken($color-primary, 5%);
    }

    &:active {
        background: darken($color-primary, 10%);
    }
}

trying to achieve:

:root {
    --color-primary: #f00;
    --color-primary-darker: #f20000  //     var(--color-primary) * 5% darker
    --color-primary-darkest: #e50000 //     var(--color-primary) * 10% darker
}

.button {
    background: var(--color-primary);
}

.button:hover,
.button:focus {
    background: var(--color-primary-darker);
}

.button:active {
    background: var(--color-primary-darkest);
}

Answer

Temani Afif picture Temani Afif · Mar 25, 2019

You can consider hsl() colors and simply control the lightness:

:root {
    --color:0, 100%; /*the base color*/
    --l:50%; /*the initial lightness*/
    
    --color-primary: hsl(var(--color),var(--l));
    --color-primary-darker: hsl(var(--color),calc(var(--l) - 5%));
    --color-primary-darkest: hsl(var(--color),calc(var(--l) - 10%)); 
}

.button {
    background: var(--color-primary);
    display:inline-block;
    padding:10px 20px;
    color:#fff;
    cursor:pointer;
}

.button:hover,
.button:focus {
    background: var(--color-primary-darker);
}

.button:active {
    background: var(--color-primary-darkest);
}
<span class="button">some text</span>

As a side note, darken() is also doing the same thing:

Makes a color darker. Takes a color and a number between 0% and 100%, and returns a color with the lightness decreased by that amount.