The other day, UI developer Alexandre Broudin asked me how I would use Sass to build a variety of palettes similar to a given palette where only the base color would change. I love playing with colors in a programmatic way so I decided to give it a try.
Let’s say you have a palette composed of 7 reddish colors. Maybe you’ve built the palette by hand in Photoshop or with Sass functions. The 4th (middle) color is the base color and there are three lighter tones of it and three darker ones.
Now you want a way to quickly produce a similar palette from another base color. Basically, you want to have another collection of colors where the difference in lightness and saturation between the base color and each color from the palette is the same. So if the difference between the lightest color and the base color is, let’s say, 28% lightness, you want the lightest color from all palettes to be 28% lighter than the base color of its own palette.
If we’ve made the first palette by hand and don’t know the color manipulations needed to have each color from the palette from the base color, how could we make all palettes identical?
Note: this article uses pieces of code from another article of mine I’ve published on The Sass Way.
Building our Functions
First, we need to initialize the default palette as a global variable.
$base-palette: (
'base': #ff6351,
'colors': #cfdfe8 #bfb9c3 #cf9192 #ff6351 #bf413c #7f3128 #732c24
) !default;
Our base palette is a map made of 2 keys: the base color, and a list of colors. The first three are the light tones, starting from the lightest. Then you have the base color again, and then the dark tones, ending with the darkest.
Now to understand why we are going to do what we are going to do, I need to explain the whole idea. If you’ve read my article at The Sass Way, it will be easier to understand but just in case you did not have a chance to read it, let me try to make this clear.
We will compute color diffs. A color diff is a map of operations to apply to a Color A in order to come up with a Color B. In our case, we will need a list of color diffs, one for each color of the palette. Each color diff will be the operations to apply to color N, in order to have the base color (or the inverse, it doesn’t matter).
Here is the color diff function:
@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)
);
}
The color-diff
function returns a map of operations to apply to the first color ($a
) to obtain the second color ($b
). That’s perfect.
Next we need a function that runs color-diff
on every color of the base palette ($base-palette
), and return a list of these diffs:
@function palette-diff($palette) {
$base: map-get($palette, 'base');
$colors: map-get($palette, 'colors');
$diffs: ();
@each $color in $colors {
$diffs: append($diffs, color-diff($base, $color));
}
@return $diffs;
}
All we need to do now is run this once and then store it in a global variable. No need to compute those diffs for each palette we’re running, only once is enough:
$base-palette: (
'base': #FF6351,
'colors': #CFDFE8 #BFB9C3 #CF9192 #FF6351 #BF413C #7F3128 #732C24
) !default;
$palette-diff: palette-diff($base-palette);
/**
* Yields a list of 7 maps (diffs)
(
(adjust-hue: 195.3931deg, desaturate: 64.78873%, lighten: 20.19608%),
(adjust-hue: 269.7931deg, desaturate: 92.30769%, lighten: 8.62745%),
(adjust-hue: 352.82536deg, desaturate: 60.75949%, lighten: 3.13725%),
(adjust-hue: 0deg, saturate: 0%, lighten: 0%),
(adjust-hue: 0.20532deg, desaturate: 47.80876%, darken: 16.66667%),
(adjust-hue: 0deg, desaturate: 47.90419%, darken: 33.13725%),
(adjust-hue: -0.13095deg, desaturate: 47.68212%, darken: 36.27451%)
)
*/
So far, so good! Only two functions left. The first one is one from the old article, applying a diff (the return of color-diff
) to a color, returning the new color.
@function apply-diff($color, $diff) {
@each $function, $value in $diff {
$color: call($function, $color, $value);
}
@return $color;
}
Here we apply each function from the diff to the color, then we get another color. Now we only need a function that creates a palette from a base color. Let’s call it create-palette
:
@function create-palette($base-color) {
$palette: ();
@each $diff in $palette-diff {
$palette: append($palette, apply-diff($base-color, $diff));
}
@return $palette;
}
At this point, we are basically done. We call the create-palette
function with a base color, and it returns a list of 7 colors (the length of the $base-palette
colors
key), made from the same operations that were used for the base palette. For instance:
$green-palette: create-palette(lightgreen);
// Returns: #f4f1f3 #d5d5d5 #c2cec0 lightgreen #79b079 #4f864f #497c49
Pretty neat, huh?
Making Things Better
A list of colors is not really the best way to deal with colors. What are you going to use? nth($green-palette, 3)
? Not really practical. What if we turned this list into a map with explicit keys like: lightest
, lighter
, light
, base
, dark
, darker
, darkest
? Then you could say map-get($green-palette, light)
.
For this, there is no sorcery. We build a function that manually turns the list of colors into the map:
@function palette($base-color) {
$colors: create-palette($base-color);
$keys: 'lightest' 'lighter' 'light' 'base' 'dark' 'darker' 'darkest';
$palette: ();
@for $i from 1 through min(length($colors), length($keys)) {
$palette: map-merge($palette, (nth($keys, $i): nth($colors, $i)));
}
@return $palette;
}
Our previous example:
$green-palette: palette(lightgreen);
/**
* Yields
(
lightest: #f4f1f3,
lighter: #d5d5d5,
light: #c2cec0,
base: lightgreen,
dark: #79b079,
darker: #4f864f,
darkest: #497c49
)
*/
Pretty cool, right?
Pushing Things Further
Things are getting quite usable here, but typing map-get(..., light)
can quickly become annoying. In order to lighten the process (see what I did there?), we could build a series of helpers:
@function lightest($palette) {
@if not map-has-key($palette, 'lightest') {
@warn "`#{inspect($palette)}` doesn't seem to have a key named `lightest`.";
}
@return map-get($palette, 'lightest');
}
@function lighter($palette) {
@if not map-has-key($palette, 'lighter') {
@warn "`#{inspect($palette)}` doesn't seem to have a key named `lighter`.";
}
@return map-get($palette, 'lighter');
}
@function light($palette) {
@if not map-has-key($palette, 'light') {
@warn "`#{inspect($palette)}` doesn't seem to have a key named `light`.";
}
@return map-get($palette, 'light');
}
And so on, you get the picture. Then you’d just do:
.el {
color: light($green-palette);
}
… which can be thought of as give me the “light” color from the $green-palette
.
Final Thoughts
As you can see, there is much we can do to make working with colors an easier task. Between lists, maps, and color functions, building color palettes has never been easier.
Hope you like the idea. There’s a demo below. You can test it out by editing the “Palettes” section in the CSS, near the bottom. Changing any one of the six colors will change the entire palette.
See the Pen Building Color Palettes with Sass by SitePoint (@SitePoint) on CodePen.
Be sure to share anything related. Cheers!Frequently Asked Questions (FAQs) on Using SASS to Build Color Palettes
What is SASS and why is it important in building color palettes?
SASS, which stands for Syntactically Awesome Stylesheets, is a CSS preprocessor that allows developers to use variables, nested rules, mixins, and functions, all in a CSS-compatible syntax. When it comes to building color palettes, SASS is incredibly useful because it allows for the creation of reusable color variables. This means that you can define a color once, and then use it throughout your stylesheet, ensuring consistency and ease of updates.
How do I define a color palette in SASS?
Defining a color palette in SASS is straightforward. You start by declaring your colors as variables. For example, $primary-color: #ff0000;
. You can then use these variables throughout your stylesheet. For instance, background-color: $primary-color;
. This ensures that your colors are consistent throughout your site and can be easily updated by changing the variable value.
Can I create a color palette from SASS variables?
Yes, you can create a color palette from SASS variables. This is done by defining your colors as variables and then using these variables to create a palette. This allows for consistency and ease of updates, as changing the value of a variable will update all instances where that variable is used.
How can I use SASS to create a CSS color palette?
Creating a CSS color palette using SASS involves defining your colors as variables and then using these variables in your CSS. For example, you might define a primary color as $primary-color: #ff0000;
and then use this variable in your CSS like so: background-color: $primary-color;
. This ensures that your colors are consistent and can be easily updated.
What are some best practices for defining a color palette in SASS?
When defining a color palette in SASS, it’s important to keep a few best practices in mind. First, use meaningful names for your variables. Instead of naming a variable $color1
, use a name like $primary-color
or $background-color
. Second, group related colors together. For example, you might group all of your primary colors together and all of your secondary colors together. Finally, comment your code. This will make it easier for others (and future you) to understand what each variable represents.
How can I use SASS functions to manipulate colors?
SASS provides a number of built-in functions that allow you to manipulate colors. For example, you can use the lighten()
function to make a color lighter, the darken()
function to make a color darker, and the mix()
function to mix two colors together. These functions can be incredibly useful when building a color palette, as they allow you to create variations of a base color.
Can I use SASS to generate a color palette automatically?
While SASS doesn’t provide a built-in way to generate a color palette automatically, you can use its features, such as variables and functions, to create a color palette with relative ease. By defining your base colors as variables and using SASS functions to create variations of these colors, you can build a comprehensive color palette.
How can I use SASS to ensure color consistency across my website?
By defining your colors as variables in SASS, you can ensure color consistency across your website. Whenever you need to use a color, you simply use the corresponding variable. This means that if you ever need to change a color, you only need to update the variable value, and the change will be reflected everywhere that variable is used.
What are some common mistakes to avoid when defining a color palette in SASS?
Some common mistakes to avoid when defining a color palette in SASS include not using meaningful names for your variables, not grouping related colors together, and not commenting your code. Additionally, it’s important to avoid hard-coding colors. Instead, always use variables. This ensures that your colors are consistent and can be easily updated.
How can I use SASS to create a responsive color palette?
Creating a responsive color palette with SASS involves using media queries in conjunction with your color variables. For example, you might define a base color as a variable, and then use a media query to change the value of that variable for different screen sizes. This allows you to adapt your color palette to different devices and screen sizes.
Non-binary trans accessibility & diversity advocate, frontend developer, author. Real life cat. She/her.