Sass Calculate Hsl Difference Between 2 Colours

SASS calculate HSL Difference between 2 colours

You can check out the following resource:

Building Color Palettes with SASS

Basically, here's the meat of it:

@function color-diff($a, $b) {
$sat: saturation($a) - saturation($b);
$lig: lightness($a) - lightness($b);
$fn-sat: if($sat > 0, 'desaturate', 'saturate');
$fn-lig: if($lig > 0, 'darken', 'lighten');

@return (
adjust-hue: -(hue($a) - hue($b)),
#{$fn-sat}: abs($sat),
#{$fn-lig}: abs($lig)
);
}

You want to do this with a function in SASS (or a parameterized mixin in LESS), and you can see the structure of one above.

Hope this helps.

Determine HSL variation to transform a color in another one

Here is the way to calculate the difference between the hue, saturation and lightness values of two colors and then use it to calculate the second color based on the first.

The individual steps are as follows:

  • Color Difference Calculation: Calculate the Hue, Saturation and Lightness differences between the two given colors by using the hue(), saturation() and lightness() functions. This function can be used separately just to output the differences alone.
  • Arriving at the secondary color based on primary: This is a three step process and they are as follows:
    • Adjust the Hue of the primary color by using the spin() function by passing the hue difference between the two colors
    • Adjust the Saturation of the Hue Adjusted color (from previous step) by using the saturate() or desaturate() functions depending on the difference.
    • Adjust the Lightness of the Saturation Adjusted color (from previous step) by using the darken() or lighten() functions depending on the difference.

This answer is a Less adaptation of this SASS Article on how to calculate one color from another.

@primary: rgb(0,100,60); /* primary color */
@secondary: rgb(185,215,50); /* secondary color */

/* mixin to calculate the difference between two given colors */
.color-diff(@color1; @color2){
@hueDiff: hue(@color2) - hue(@color1);
@saturationDiff: saturation(@color1) - saturation(@color2);
@lightnessDiff: lightness(@color1)- lightness(@color2);

color1: @color1; color2:@color2; /* just for testing, can be removed */
}

/* Step 1: mixin to adjust the hue difference between the colors */
.adjust-hue(@color; @diff){
@hueAdjusted: spin(@color, @hueDiff);
}

/* Step 2: mixin to adjust the saturation difference */
.adjust-saturation(@color; @diff) when (@diff > 0){
@satAdjusted: desaturate(@color, abs(@diff)); /* desaturate if diff is greater than 0 */
}
.adjust-saturation(@color; @diff) when not (@diff > 0){
@satAdjusted: saturate(@color, abs(@diff)); /* saturate if diff is not greater than 0 */
}

/* Step 3: mixin to adjust the lightness diff between the colors */
.adjust-lightness(@color; @diff) when (@diff > 0){
@lightnessAdjusted: darken(@color, abs(@diff)); /* darken if diff is greater than 0 */
}
.adjust-lightness(@color; @diff) when not (@diff > 0){
@lightnessAdjusted: lighten(@color, abs(@diff)); /* else lighten */
}

div{
.color-diff(@primary; @secondary);
.adjust-hue(@primary; @hueDiff);
.adjust-saturation(@hueAdjusted; @saturationDiff);
.adjust-lightness(@satAdjusted; @lightnessDiff);
color: @lightnessAdjusted; /* final output value */
}

Compiled CSS:

div {
color1: #00643c;
color2: #b9d732;
color: #b9d732;
}

If you would just wish to obtain the differences between two colors, then you could use a loop like below to output the differences in terms of hue, saturation and lightness values.

@color-list-1: rgb(0,100,60), #B0BCA7, #ABCDEF; /* list of primary colors */
@color-list-2: rgb(185,215,50), #BADA55, #FEDCBA; /* list of secondary colors */

#output{
.loop-colors(@index) when (@index > 0){
@primary: extract(@color-list-1, @index);
@secondary: extract(@color-list-2, @index);
.color-diff(@primary; @secondary);

/* output the values of the comparison */
color-comparison-@{index}+: ~"Hue Difference: @{hueDiff}";
color-comparison-@{index}+: ~"Saturation Difference: @{saturationDiff}";
color-comparison-@{index}+: ~"Lightness Difference: @{lightnessDiff}";
.loop-colors(@index - 1);
}
.loop-colors(length(@color-list-1));
}

The above code will compare the corresponding values in both lists and output their difference like below:

#output {
color-comparison-3: Hue Difference: -180, Saturation Difference: -29.142857142857153%, Lightness Difference: -5.882352941176478%;
color-comparison-2: Hue Difference: -19.849624060150404, Saturation Difference: -50.70282063269439%, Lightness Difference: 10.196078431372548%;
color-comparison-1: Hue Difference: -85.09090909090908, Saturation Difference: 32.65306122448979%, Lightness Difference: -32.352941176470594%;
}

How to obtain the SASS function that associates two specific colours?

You can use online tool to find that for you such as Sass Colour Function Calculator.

In your example:

$light-green: #99E2D0;
$dark-green: darken(saturate($light-green, 44.27), 47.84);

SASS detect colour darkness to determine styles

As per the documentation, whiteness and blackness are related to HWB color model. If you can work with HSL model then lightness can be used as follows:

$white: #fff;
$text: #393939;
$font-std: 18px;
$transition-std: 0.4s ease all;
$primary: #f8e421;
$secondary: #354052;

@function contrastText($color) {
$result: invert($color);
$lightness: lightness($result);
@if ($lightness < 50) {
$result: black;
}
@return $result;
}

@mixin buttonStyles($color) {
font-size: $font-std;
padding: 1rem 3rem;
background-color: $color;
color: contrastText($color);
transition: $transition-std;

&:hover {
cursor: pointer;
background-color: lighten($color, 15%);
}
&:focus {
background-color: lighten($color, 10%);
}
&:active {
background-color: lighten($color, 25%);
}
}
.btnPrimary {
@include buttonStyles($primary);
}
.btnSecondary {
@include buttonStyles($secondary);

}
.btnTest {
@include buttonStyles(#888);
}

After compilation it'll look like this: jsfiddle

/* CSS compiled from SASS*/
.btnPrimary {
font-size: 18px;
padding: 1rem 3rem;
background-color: #f8e421;
color: black;
transition: 0.4s ease all;
}

.btnPrimary:hover {
cursor: pointer;
background-color: #faed6b;
}

.btnPrimary:focus {
background-color: #faea52;
}

.btnPrimary:active {
background-color: #fcf39d;
}

.btnSecondary {
font-size: 18px;
padding: 1rem 3rem;
background-color: #354052;
color: #cabfad;
transition: 0.4s ease all;
}

.btnSecondary:hover {
cursor: pointer;
background-color: #536480;
}

.btnSecondary:focus {
background-color: #495871;
}

.btnSecondary:active {
background-color: #697d9e;
}

.btnTest {
font-size: 18px;
padding: 1rem 3rem;
background-color: #888;
color: black;
transition: 0.4s ease all;
}

.btnTest:hover {
cursor: pointer;
background-color: #aeaeae;
}

.btnTest:focus {
background-color: #a2a2a2;
}

.btnTest:active {
background-color: #c8c8c8;
}

.testRed {
font-size: 18px;
padding: 1rem 3rem;
background-color: red;
color: cyan;
transition: 0.4s ease all;
}

.testRed:hover {
cursor: pointer;
background-color: #ff4d4d;
}

.testRed:focus {
background-color: #ff3333;
}

.testRed:active {
background-color: #ff8080;
}

.testGreen {
font-size: 18px;
padding: 1rem 3rem;
background-color: green;
color: #ff7fff;
transition: 0.4s ease all;
}

.testGreen:hover {
cursor: pointer;
background-color: #00cc00;
}

.testGreen:focus {
background-color: #00b300;
}

.testGreen:active {
background-color: lime;
}

.testBlue {
font-size: 18px;
padding: 1rem 3rem;
background-color: blue;
color: yellow;
transition: 0.4s ease all;
}

.testBlue:hover {
cursor: pointer;
background-color: #4d4dff;
}

.testBlue:focus {
background-color: #3333ff;
}

.testBlue:active {
background-color: #8080ff;
}

.testOrange {
font-size: 18px;
padding: 1rem 3rem;
background-color: orange;
color: #005aff;
transition: 0.4s ease all;
}

.testOrange:hover {
cursor: pointer;
background-color: #ffc04d;
}

.testOrange:focus {
background-color: #ffb733;
}

.testOrange:active {
background-color: #ffd280;
}

.testPurple {
font-size: 18px;
padding: 1rem 3rem;
background-color: purple;
color: #7fff7f;
transition: 0.4s ease all;
}

.testPurple:hover {
cursor: pointer;
background-color: #cc00cc;
}

.testPurple:focus {
background-color: #b300b3;
}

.testPurple:active {
background-color: magenta;
}

.testYellow {
font-size: 18px;
padding: 1rem 3rem;
background-color: yellow;
color: blue;
transition: 0.4s ease all;
}

.testYellow:hover {
cursor: pointer;
background-color: #ffff4d;
}

.testYellow:focus {
background-color: #ffff33;
}

.testYellow:active {
background-color: #ffff80;
}
<button class='btnSecondary'>secondary</button>
<button class='btnPrimary'>primary</button>
<button class='btnTest'>test</button>
<hr>
<button class='testRed'>Red</button>
<button class='testGreen'>Green</button>
<button class='testBlue'>Blue</button>
<button class='testOrange'>Orange</button>
<button class='testPurple'>Purple</button>
<button class='testYellow'>Yellow</button>

Get individual HSL values from hex with SASS

You could use the built-in lightness function which returns the HSL lightness of $color as a number between 0% and 100%.

$blue: blue;

@mixin text-color($color) {
color: if(lightness($color) > 50%, #000, #fff);
}

.something {
background-color: $blue;
@include text-color($blue);
}

Also, note that you could use a function instead, so you won't be limited to the color property only.

$blue: blue;

@function text-color($color) {
@if lightness($color) > 50% {
@return #000;
} @else {
@return #fff;
}
}

.something {
background-color: $blue;
color: text-color($blue);
}


Related Topics



Leave a reply



Submit