Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Color operations in less

I'm already using color theme in my website, where, for example I have a standard hex color for link states regular/hover/active.

Now I want to use color operations in LESS like color:darken(@base_color, x%);

So my question is:

If I know my base color and my output color after the 'darken' operation,

how do I know what % to give the darken operation to produce my output color?

eg: If i'm going from #952262 -> #681744 what would be my %?

Maybe there's a site that does these conversions?

Hopefully the answer is not 'Trial and error'.

like image 485
Danield Avatar asked May 01 '13 06:05

Danield


3 Answers

Has A Few Challenges and Caveats

Normally, people do not use a function like darken() to get a color that they already know they want to end up at (they just put the color value they already know they want). However, I will assume there is more behind this question than that.

The darken() Function

The darken() function of LESS affects the "brightness" or "lightness" portion of a color considered from the viewpoint of its hsl settings (hue, saturation, lightness). Here's your two colors considered from that view (based on this site, I have noticed some variations between sites--some are probably more accurate than others):

#952262 = hsl(327, 63%, 36%)
#681744 = hsl(327, 64%, 25%)

So the darkness value you seek can be hand calculated from that site, by just a subtraction, 36% - 25% = 11%. Plugging that into your function:

darken(@base_color, 11%);

Yields

#671844 /* not 681744! */ 

Hey! That Didn't Match My Target!

Notice that the s (saturation) value above shows as different by 1% from your base to your target, which means that technically you cannot get from your base color to the target color purely through the darken() function. Instead, you either need to use another function to tweak the s value also, or your target should be adjusted slightly to the following (which keeps s at 63%):

#681844 = hsl(327, 63%, 25%)

But that number (#681844) still does not match the LESS output (#671844). The website shows the LESS output as being hsl(327, 62%, 25%) (notice the saturation value dropped to 62%). I suspect what this means is a difference in rounding calculations between the website calculations and the LESS function calculations. This may well be why your original number was off by 1% on saturation as well, whatever program you used rounded differently than the website also. This is probably not a big issue, as it gets you close to your target value.

Using LESS to Calculate It

Now, depending on what your actually doing, you can use LESS to calculate that percentage, instead of hand calculating it, using the lightness() function. Assume you had adjusted your target to #681844 based off the website. Then this is an example of getting the percentage you want (I use a fake property color-calc to show the calcuation:

@base_color: #952262;  /* Base #952262 = hsl(327, 63%, 36%) */
@real_target_color: #681844; /* Real Target #681844 = hsl(327, 63%, 25%) */
@color_calc: (lightness(@base_color) - lightness(@real_target_color));

.test {
  color-calc: @color_calc;
  color: darken(@base_color, 11%);
} 

Outputs:

.test {
  color-calc: 11%;
  color: #671844;
}

Notice that it calculated the 11% difference in darkness. Also, notice that it still ends up with a value slightly different than target because of that (I suppose) rounding issue. Plugging in the final value LESS generates (#671844) as the target still yields the same 11% value for darken().

like image 179
ScottS Avatar answered Oct 08 '22 09:10

ScottS


LESS has the function lightness(), that returns the lightness channel of a color in the hsl space.

So, obviously

lightness(hsl(90, 100%, 50%))

would return

50%

but you can do something more sophisticated, like a mixin, that calculates the lightness difference between two colors:

@nice-blue: #5B83AD;
@lighter-blue: #6F92B7;

.test(@color1, @color2) {
  @lightdif: (lightness(@color1) - lightness(@color2));
  color1: @color1;
  color2: @color2;
  lightness-dif:  @lightdif;
}

.test {
   .test(@lighter-blue, @nice-blue);
   output-color: lighten(@nice-blue, @lightdif);
}

which would return:

.test {
  color1: #6f92b7;
  color2: #5b83ad;
  lightness-dif: 6%;
  output-color: #6f92b7;
}

In your case (#952262 -> #681744) the lightness-dif would be 11%.

Now you can play with this a little, for example with guards, you can define which color is darker/lighter and use the absolute difference, depends on what exactly you want to use it for.

For more color operations you can read lesscss.org under "Function Reference" -> "Color functions".

And if you are using a javascript implementation of less you can do even more using javascript interpolation (with back-ticks) and javascript functions inside LESS.

like image 8
Martin Turjak Avatar answered Oct 08 '22 07:10

Martin Turjak


I created a tool that suggests color functions, since this bugs me on a daily basis. It lists most of the LESS functions that get from one color to another, so that you can focus on whether using darken or softlight with a color, makes more sense in terms of your design.

Suggest color function transition

like image 7
Alex Gyoshev Avatar answered Oct 08 '22 09:10

Alex Gyoshev