I'm designing some colored blocks, where the text is one color and the background is a lighter / desaturated shade of that same color (think warning text, where the words is red and it has a light pinkish background).
The text color is #990000. The background color is #f2dede. In Photoshop HSV, that equates to hsv( 0, 100%, 60%) & hsv(0, 8%, 95%).
With this color set, I'd like to be able to toss in other colors -- a nice green or yellow -- and have the background automatically calculated.
Using LESSCSS, I've tried:
@color: desaturate( lighten( hsv(0, 100%, 60%), 35%), 92% );
But I can't get it to render the color I generate by performing the same changes in Photoshop.
The color theory of this is beyond my comprehension, but my question is: How do I convert one color to another color, given the Photoshop HSB values?
Update:
I get it a little better -- the L and the B in HSB and HSL are not at all compatible, so lightening the color the "B" delta is never going to work.
It's sloppy, but something like this works:
@foreground: #990000;
@background: hsv(hsvhue(@foreground),
(hsvsaturation(@foreground)-92%),
(hsvvalue(@foreground)+35%));
Lacking a "value" command similar to lighten/darken, I'm thinking this is the best I'm going to get. (If I don't get any other responses, I'll mark this the answer).
Thanks much...Nate
Note: my answer here discusses some issues with color theory and LESS functions that you may find useful also.
For LESS 1.4 (which has some new built in functions)
LESS
@color: hsv(0, 100%, 60%);
@bkg: hsv(hsvhue(@color), (hsvsaturation(@color) - 92%), (hsvvalue(@color) + 34.75%));
.test {
color: @color;
background-color: @bkg;
}
CSS Output
.test {
color: #990000;
background-color: #f2dede;
}
The link I posted above may explain why my value is 34.75%
and not 35%
more like your numbers were expecting.
UPDATE: I just noticed that you had essentially posted a similar answer in your question. I'm not certain exactly what issue you are still facing with that method of calculation.
UPDATE 2: If you desire it to generally always "contrast" then something like this may work better:
@color: hsv(0, 100%, 60%);
@darkerBkg: hsv(hsvhue(@color), (hsvsaturation(@color) - 92%), (hsvvalue(@color) + 34.75%));
@lighterBkg: hsv(hsvhue(@color), (hsvsaturation(@color) + 92%), (hsvvalue(@color) - 34.75%));
@bkg: contrast(@color, @darkerBkg, @lighterBkg, 43%);
.test {
color: @color;
background-color: @bkg;
}
Using the contrast
function with the default 43%
threshold value will cause a "flip" to the @lighterBkg
in this case at a 35%
saturation value (hsv(0,35%,60%)
).
The calculation numbers you have set are going to work best with colors in the initial saturation range of 92-100
(or with the contrast
feature also 0-8
), and initial value range of 0-65
(or with contrast
you would probably be covered in any value range). In the contrast
version, any saturation between 9-91
will begin to "equalize" to either 0%
or 100%
. You would need to decide on a new "calculation" and add some other math logic in if that was an issue, but I think with the contrast
version it may not be a problem.
Give this tool a try:
Cuttle - Color function suggestions based on example
https://www.ofcodeandcolor.com/cuttle/
It takes two different input colors and calculates (or approximates) different ways of going from one color to the other using Less or Sass color functions. Created by @alex-gyoshev.
You'd have to convert your hsv values to rgb first, whilst taking into account the tipps from ScottS about the different color spaces.