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()
andlightness()
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()
ordesaturate()
functions depending on the difference. - Adjust the Lightness of the Saturation Adjusted color (from previous step) by using the
darken()
orlighten()
functions depending on the difference.
- Adjust the Hue of the primary color by using the
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
Webkit CSS to Control the Box Around the Color in an Input[Type=Color]
How to Keep CSS Floats in One Line
How to Target Microsoft Edge with CSS
How to Remove All Default Webkit Search Field Styling
Less and Bootstrap: How to Use a Span3 (Or Spanx [Any Number]) Class as a Mixin
Force Sidebar Height 100% Using CSS (With a Sticky Bottom Image)
CSS Grid Auto Fit with Max-Content
Fix Custom Font Line-Height with CSS
CSS Selector for Not a Child of Element Type
Importance of CSS Stylesheet Hierarchy
How to Delay the Start of a CSS Animation
Sass Calculate Hsl Difference Between 2 Colours
Less Loops Used to Generate Column Classes in Twitter - How Do They Work
How to Use and How Works CSS' Will-Change Property