By Chris Eppstein and Michael Parenteau
These ideas build on ones proposed by Tab Atkins but expand the concepts to apply to any color value, not just named colors.
They provide the full power of Sass's color system while preserving a more human-readable system when multiple transformations are applied because the arguments are closer to the operations.
In color manipulation there are two basic classes of operations:
- Adjustment: adds or subtracts an absolute amount and stops when it gets to the end point.
- Scaling: percent change from the current value towards the end point.
The convention used here is to use a past-tense verb for adjustment and an active tense verb for scaling.
Almost all of these operations take place in the HSL color domain (the
exception being inverted
which is RGB based.)
These operations can be composed in any order however, in some cases different ordering may result in a different resulting color.
While it's a bit tricky, this system can be implemented in Sass to elicit early feedback from users.
For named colors only, you can use an adjacent color name to transform the hue. Such operations are nonsensical for arbitrary colors.
In sass, we cannot distinguish a named color from an arbitrary color, so we'd
probably just enforce this by saying that the hue of the color modifier cannot
be more than 30deg
away from the primary color's hue. This might make sense
in CSS as well.
color(green blue) // 50% between green and blue
color(greenish blue) // 25% towards green from blue
color(blueish green) // 25% towards blue from green
color(blueish(33%) green) // 33% towards blue from green
It is handy to be able to find the compliment and inverse of a color.
color(compliment $color) // compliment color
color(inverted $color) // inverted color
Other hue manipulations make colors warmer or cooler. We believe that generic degree manipulation of an arbitrary color is non-sensical from a design persepective.
Note: we're not sure what is the "hottest" color because there are two primary colors considered "hot": red and yellow. Yellow is the opposite hue of blue on the wheel but orange is the opposite hue of blue in terms of pigments. This will make a good bikeshed (every proposal needs one).
color(warmer $foo) // rotate 50% percent towards orange(or yellow?) (scaling)
color(cooler $foo) // rotate 50% percent towards blue (scaling)
color(warmer(25%) $foo) // rotate 25% percent towards orange (scaling)
color(cooler(25%) $foo) // rotate 25% percent towards blue (scaling)
color(warmed(30deg) $foo) // rotate 30deg percent towards orange (adjustment)
color(cooled(30deg) $foo) // rotate 30deg percent towards blue (adjustment)
lightened
and darkened
will adjust the lightness of a color.
color(lightened $color) // +50% lightness adjustment
color(lightened(33%) $color) // +33% lightness adjustment
color(darkened $color) // -50% lightness adjustment
color(darkened(33%) $color) // -33% lightness adjustment
lighter
and darker
will scale the lightness of a color.
color(lighter $color) // +50% lightness scaling
color(lighter(33%) $color) // +33% lightness scaling
color(darker $color) // -50% lightness scaling
color(darker(33%) $color) // -33% lightness scaling
saturated
and desaturated
will adjust the saturation of a color.
color(desaturated $color) // -50% saturation adjustment
color(desaturated(33%) $color) // -33% saturation adjustment
color(saturated $color) // +50% saturation adjustment
color(saturated(33%) $color) // +33% saturation adjustment
saturate
and desaturate
will scale the saturation of a color.
color(desaturate $color) // 50% saturation scaled
color(desaturate(33%) $color) // 33% saturation scaled
color(saturate $color) // 50% saturation scaled
color(saturate(33%) $color) // 33% saturation scaled