Aesthetic Sass 2: Colors and Palettes

Color is very important in design – it plays both a visual and psychological role. Having a varied palette that matches the intent of your design greatly contributes to the overall aesthetic of your site.

You or your designer might already have a palette in mind for your project. If not, I highly recommend reading up on color theory for designers and creating your own color palettes. Ideally, a good palette will consist of either two contrasting “brand colors” or two similar colors (from a monochromatic scheme), and a few lighter or darker colors for versatility.

Assuming you have your color palette chosen, the built-in color functions in Sass can be used to manipulate these colors.

Referencing the Color Palette

Sass $variables provide a great way to reference color values in an organized, reusable way. It is highly suggested that palette colors are named semantically rather than on their appearance. A variable like $color-blue has little meaning (other than that the color is blue), whereas $color-primary defines the color’s role semantically. This also allows for flexibility for multiple themes, or if brand colors change in the future.

Though $color-variables are a good start, it is often a good idea to keep color variables organized in a Sass map. This way, the colors can be iterated, are more organized, and are more intuitive to reference.

Below is a base color palette pulled from Scotch.io:


$scotch-colors: (
  'primary': #8e3329, 
  'accent': #d98328,
  'secondary': #5a1321,
  'foreground': #191919,
  'background': #e9e9e9
);

Each color has a semantic meaning that describes the color’s role. The Sass function map-get(), or a custom utility function (recommended), can be used to reference individual colors:


@function scotch-color($key: 'primary') {
  @return map-get($scotch-colors, $key);
}

$button-color: scotch-color('primary'); // #8e3329

A color palette should be limited in the number of colors it contains (aim for 4 – 7 colors). Other colors can be derived from tints and shades of the palette colors.

Tints and Shades

Adding tints and shades to your color palette will give you a greater number of colors to work with in your project, while still achieving consistency and adhering to your original color palette. To get the tints and shades of a color in Sass, the mix() function can be used with white and black, respectively:


$color-primary: scotch-color('primary'); // #8e3329

$color-primary-tinted: mix(white, $color-primary, 10%); // #99473e
$color-primary-shaded: mix(black, $color-primary, 10%); // #7f2d24

If the tint/shade interval is established, a utility function can be provided that can return the shade/tint of the desired color, to the desired level (which is good for preventing magic numbers):


$color-interval: 10% !global;

@function scotch-color-level($color-name: 'primary', $level: 0) {
  $color: scotch-color($color-name);
  $color-base: if($level < 0, black, white);

  @return mix($color-base, $color, $level * $color-interval);
}

// Example:
.panel {
  background-color: scotch-color-level('primary', 2);
}

Sass also provides a scale-color() function that allows the red, green, blue, saturation, lightness, and alpha components of a color to be manipulated based on the scale the color is already at. That is, if a color is already light, increasing the $lightness component won’t lighten it by as much as that of a darker color.

The lighten() and darken() output similar colors, but colors can blow out quickly with these functions. Keep that in mind if you decide to use them.

Opacity and Transparency

A project design can be greatly enhanced by including thoughtful levels of transparency with the project’s color palette. Transparency is contextual – its effectiveness in a design is based on the background that it covers. Transparency is mainly used to create contrast, and with different colors and backgrounds, the opacity level to achieve effective contrast may vary.

With that said, it’s a good idea to aggregate the different (semantic) levels of opacity used in a project’s design with Sass maps:


$scotch-opacity: (
  'light': 0.8, // opacity used with lighter colors
  'dark': 0.4   // opacity used with darker colors
  // ... etc.
);

A utility scotch-color-alpha() function can be provided to adjust the color based on a given $opacity level using the rgba() function:


@function scotch-color-alpha($name: 'primary', $opacity: 0) {
  $color: scotch-color($name);

  // Get the named opacity level, if it exists
  @if map-key-exists($scotch-opacity, $opacity) {
    $opacity: map-get($scotch-opacity, $opacity);
  }

  // Use rgba() to manipulate the color's alpha level
  @return rgba($color, $opacity);
}

// Example usage:
$button-transparent-color: scotch-color-alpha('primary', 'light');
// => rgba(#8e3329, 0.8)

The opacify() and transparentize() functions may also be used to decrease/increase transparency respectively. These functions are really only useful if the color already has transparency. However, a well-established color palette should be based on fully opaque colors.

Contrast and Accessibility

When deciding which two colors make a good foreground/background color pair, it might be tempting to use the lightness($color) function to conditionally choose a foreground color:


// Returns either a dark or light foreground color, given
// the background color
@function scotch-foreground-color($bgcolor, $threshold: .65) {
  @return if(lightness($bgcolor) >= $threshold, $color-dark, $color-light);
}

This works for many scenarios, but can throw false positives/negatives for colors near the $threshold. Alternatively, it is recommended that contrast between color pairs are manually checked, especially for accessibility.

The Web Content Accessibility Guidelines state that the contrast ratio between foreground images/text and a background should be at least 4.5:1 (3:1 for larger text) for level AA, and 7:1 (4.5:1 for larger text) for level AAA. You can read more about the contrast minimum to understand the rationale and how this value is calculated.

Thankfully, Lea Verou has created a handy tool for checking color contrast that should come in handy as you are choosing color pairs. Combining the primary color in the example palette, Scotch red (#8e3329), and the 'light' color, white (#ffffff), yields a contrast ratio of 7.9, which is acceptable for any size text at all levels. This would make a good background/foreground color pair!

Custom Color Variants

Sometimes, a project will have custom color variants provided by a designer. This makes it easier to determine what the various shades and tints of each color in the palette will be (as they are provided in advance). This also means that we can’t take advantage of the convenience of a color shade/tint function. Google’s Material Design is a good example of carefully chosen color variants arranged as a spectrum for each base color:

Screen Shot 2015-03-29 at 4.07.22 PM

Multidimensional (nested) Sass maps should be used for custom color variants when they are provided. Here’s how the original color palette and color function can be adapted for custom colors:


$scotch-color-key: 'base' !default;

$scotch-colors: (
  'primary': (
    'base': #8e3329,
    'light': #d9534f,
    'dark': #c9302c
  ),
  'accent': (
    'base': #d98328,
    'light': #dd8f3d,
    'dark': #c57623
  ),
  'secondary': (
    'base': #5a1321,
    'light': #7b1a2d,
    'dark': #51111e
  ),
  'foreground': (
    'base': #191919,
    'light': #333333,
    'dark': #111111,
    'darker': #000000
  ),
  'background': (
    'base': #e9e9e9,
    'light': #ffffff,
    'dark': #dddddd
  )
);

The modified scotch-color() function to handle specific color variants can be seen in this Sassmeister.

The base (default) color key is defined in $scotch-color-key. The scotch-color() function is modified above to retrieve a specific color variant based on the variant key, and desired opacity setting. With this, a color can still be retrieved with only one argument; e.g. $color: scotch-color('primary').

See the Pen 0d74b9a54fb2ebc3c3be270284ed618d by David Khourshid (@davidkpiano) on CodePen.

Conclusion

Colors are a very important part of a design project. As such, it is best to organize a project’s color palette in a Sass map to easily reference specific colors with map-get or a utility function (however you choose to implement it). Sass provides a variety of color functions to manipulate colors to produce shades and tints for a fuller color spectrum. For custom colors, use multidimensional color maps for organization.

The overall goal for an aesthetic, colorful design in Sass is to be able to:

  • provide and reference colors that fit cohesively with the given color palette, and…
  • prevent magic (hex) numbers.

Keep an eye out for the next article in the series, Aesthetic Sass 3: Typography and Vertical Rhythm!

David Khourshid

David Khourshid is a front-end web developer in Orlando, Florida. He is passionate about JavaScript, Sass, and cutting-edge front-end technologies. He is also a pianist and enjoys mathematics, and is constantly finding new ways to apply both math and music theory to web development.