1

I have several colors in HSL format, this one of them: 284, 3, 30.

I need to create a Sass mixin for the developers where all they need to do is add or subtract 50% of the Lightness value (30) in order to achieve the desired color as per our brand guidelines.

What I currently have works to a certain extent:

@mixin smoke($l:30) {
    color: hsl(284, 3, $l);
}

So if the developer wants to add 50% to the Lightness (+15), they could do this:

@include smoke(45);

And for the lighter color (-15), they would do this:

@include smoke(15);

The problem with this approach is that the developers HAVE to remember the Lightness values of all the colors (or go back to the guidelines over and over) in order to determine what is the 50% of a particular color that they need to use and then manually add that value to the argument. Makes sense?

What I'm looking for is a way to create a mixin that allows the developers to just reference the color name in the @include directive and then just type (+50%) or (-50%) in the argument, then when the CSS is compiled it would look like this:

  • Darker color: 284, 3, 15 (Lightness has been reduced by 50% of 30).
  • Lighter color: 284, 3, 45 (Lightness has been increased by 50% of 30).

If I do @include smoke(+50%); or @include smoke(-50%); I get totally different colors.

Here's my initial Sass I've been working with:

//Color
@mixin smoke($l:30) {
    color: hsl(284, 3, $l);
}

body {
    /*DOES WORK BUT NOT IDEAL METHOD*/
    /*Light = #746f77*/
    @include smoke(45);
    /*Dark = #272527*/
    @include smoke(15);
    /*===========*/
    /*DOESN'T WORK BUT IDEAL METHOD*/
    /*Light = #746f77*/
    @include smoke(-50%);
    /*Dark = #272527*/
    @include smoke(+50%);
}

https://codepen.io/ricardozea/pen/VgRVbG?editors=0100

Thank you.

Ricardo Zea
  • 10,053
  • 13
  • 76
  • 79

3 Answers3

0

you gave the wrong value because in HSL values are in %(percentage)

hsl(284%, 3%, 45%)

you don't need to use

 @include smoke(-50%);
 /*Dark = #272527*/
 @include smoke(+50%);

because when you give these argument to mixin smoke(+50%); or smoke(-50%); and sass compiles it and convert these values into

hsl(284%, 3%, +50%) or hsl(284%, 3%, -50%) 

thats why you get different colors and in negative value you get no color

Hammad tariq
  • 184
  • 9
  • Thanks for your reply. A few things to note: You can either omit the `%` symbol or you can add it if you want, it's not required in Sass. Same thing for other values, for example in the `lighten()` function: You can write `lighten(red, 50%)` or `lighten(red, 50)`. Also, Sass only compiles `hsl` nor `hsla` to HEX format or HTML color names (weird if you ask me). Also, when I use the negative value `@include smoke(-50%);` I do get a color, I get `color: black;`. Check out the Pen and click on 'View Compiled CSS'. Thanks. – Ricardo Zea Feb 21 '19 at 04:40
  • when you use the negative value `@include smoke(-50%);`you get a `color: black;`because black is default color of text by browser sass can't compile or understand negative value and you are right that the `% `symbol is optional but i am saying that in `HSL` scheme your color values render in % (percentage) so thats why you can get the different value at ` @include smoke(+50%); @include smoke(45); @include smoke(15);` – Hammad tariq Feb 21 '19 at 05:59
  • I get color `black` using `-50%` because I'm removing so much lightness from the source color that it reaches black, not because it's the default color in browsers. You said _"…and in negative value you get no color"_. Black is a color though. Also, Sass DOES compile just fine, no errors at all, I'm getting `black` (regardless if it's the color I need or not). I'm using argument values like `(-50%)` and `(+50%)` as examples to convey my idea, not because I'm expecting it to work like that. Either way, my question is still unanswered. Thank you. – Ricardo Zea Feb 21 '19 at 13:19
0

Here's the solution I came up with.

Since I posted the question things have changed. Now I not only need to modify the Lightness by 50% but actually by quarters, like 25%, 50%, and 75%, for each color.

So in a comment block in my SCSS file, I have a list of the Lightness values I need for all my colors, in this case we're only addressing my "Smoke" color which has a Lightness value of 30.

Taking my initial color mixin:

//Color
@mixin smoke($l:30) {
    color: hsl(284, 3, $l);
}

…if I want to add 25% Lightness to 30, I do this:

.selector {
    @include smoke(30*1.25);
}

Sounds very stupid once you understand it, I know, so bear with my explanation:

What this does is that it multiplies 30 by itself (by 1) and then adds 25% of itself (.25). It's basically the same as doing 30 + 7.5.

Which turns out to be hsl(284, 3, 37.5) which is exactly what I needed. Keep in mind though that Sass renders HSL and HSLA color modes in HEX values. ¬¬ I know right?

All examples together

Here's how to use this approach to add and subtract 25%, 50%, and 75% Lightness from a color.

Lighter color (increase Lightness):

+25% Lightness

.selector {
    @include smoke(30*1.25);
}

+50% Lightness

.selector {
    @include smoke(30*1.5);
}

+75% Lightness

.selector {
    @include smoke(30*1.75);
}

Darker color (reduce Lightness):

-25% Lightness

.selector {
    @include smoke(30/1.25);
}

-50% Lightness

.selector {
    @include smoke(30/1.5);
}

-75% Lightness

.selector {
    @include smoke(30/1.75);
}

The beauty of this method is that if I need to add more color ranges, say, every 10%, all I need to do is change the decimal values to multiples of 10, like this for example:

.selector {
    @include smoke(30*1.20);
}

or

.selector {
    @include smoke(30/1.60);
}

The only downside to this method is that the developer has to know the specific Lightness value of a color because it has to be hardcoded into the argument. But that's why I have a list of the Lightness values I need for all my colors in a comment block at the bottom my SCSS file ¯_(ツ)_/¯.

If you have a better way to accomplish this, please post your answer.

Thanks.

Community
  • 1
  • 1
Ricardo Zea
  • 10,053
  • 13
  • 76
  • 79
0

The scale-color built-in function in sass already makes provision for this. this is a solution using the scale-color function in the color module

@mixin smoke($color, $l){
  background: scale-color($color, $lightness: $l)
}

then to increase the lightness by 50%

body{
  @include smoke(hsl(284%, 3%, 30%), +50%);
}