Thinking in Design Systems — Colors

Alex Korzh
5 min readApr 9, 2020

--

There are a lot of approaches to kicking off a design system for your web application — This article is part of a series on “design systems” and the challenges we faced with building our own. Let’s take a look at how to build a color system, and what are the best practices to make it simple and scalable.

Who are we?

We are the team of passionate makers who created a component library (we call it Rene) for Relate. What is Relate? Glad you asked. Relate is a visual visual development environment for fast, live collaboration. And… For designing systems. 🔥 We have already launched! Check it out.

Who is this article for?

It will be useful for both designers and developers, it doesn’t matter which tool you are using, all principles are the same and can be applied both with code or design tools such as Sketch or Figma 👌.

Ok, let’s start!

Colors

The essential color palette

Primary colors

These colors displayed most frequently across your app. They can represent active states, accent elements or text-color.

https://cdn-images-1.medium.com/max/1600/1*eSdLzb5l8yo9q4lj5UW-EA.png

Secondary colors

Secondary colors are optional, but they provide more opportunities to distinguish your product. These colors are used less often to emphasize or accent elements. Secondary and tertiary color palettes are often used in complex products.

Shades

Use the primary or secondary palette to create shades. In the theming section, I will show you how we сoped with it.

Keep your color palette as simple as possible, because it’s easy to maintain and scale your design system through the component library, also try to use shades and colors wisely for consistency and scalability.

“Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple. But it’s worth it in the end because once you get there, you can move mountains.” — Steve Jobs.

Naming your colors

When it comes to naming color variables, there are two main approaches: semantic and declarative. Neither of them is wrong.

The Semantic approach works better for massive and scalable design systems, while the declarative approach is used for small independent modules.

Semantic naming — “What is it representing?”

Every component in your system has different states such as initial, active, error, success, hover, etc. Every state could be represented by different colors and this is where the naming convention would come in handy. To make it happen we applied the theming approach. For each state of the element, we used different themes represented by different colors.

const colorPalette = {
primary: '#4040FF',
secondary: '#A640FF',
tertiary: '#FF40DC',
primaryForeground: '#333333',
secondaryForeground: '#333333',
tertiaryForeground: '#444444',
primaryBackground: '#FFFFFF',
secondaryBackground: '#FFFFFF',
tertiaryBackground: '#F3F3F3',
active: '#FFFFFF',
warning: '#FF4040'
}

Declarative naming — “What is it?”

You can use declarative naming for components that are used independently from the main system. It’s really easy to use and will be encapsulated from your main color palette.

const colorPalette = {
white: '#FFFFFF',
red: '#FF4040',
black: '#000000'
}

Theming

Once you created your essential color palette, you can use it across the design system and set palette values to your CSS properties depending on your themes. In Rene, we are using styled-components for theming. I can assure you that these principles will work for other conventions such as CSS variables, CSS modules, etc.

Let’s take a look at the Tree-Element component:

Initial Theme

https://cdn-images-1.medium.com/max/1600/1*XVncl18M07LxhEKnGCutYA.png
const initialTheme = {
color: primaryForeground, // #333333
background: primaryBackground, // #FFFFFF
borderWidth: '1px',
borderStyle: 'solid',
borderColor: primary // #4040FF
};

Primary Theme

https://cdn-images-1.medium.com/max/1600/1*MLCWipn2-wwozk84wwV6Hw.png
const primaryTheme = {
color: active, // #FFFFFF
background: primary, // #4040FF
borderWidth: '1px',
borderStyle: 'solid',
borderColor: primary // #4040FF
};

As you can see we created two different themes to describe two different component states, the difference between them is only in palette values.

We also found that using objects for theme description is very convenient, and this approach can be used for describing error, success or other states of the element.

The final styled object which will be compiled into pure CSS will look like this:

const style = {
color: theme.color,
background: theme.background,
borderWidth: theme.borderWidth,
borderStyle: theme.borderStyle,
borderColor: theme.borderColor
};

If you want to change the primary theme of the element to the secondary, you only need to pass specific property:

React component -> <TreeElement secondary/>
https://cdn-images-1.medium.com/max/1600/1*5QrabV21KJy-3qtfFJj7Zw.png
const secondaryTheme = {
color: active, // #FFFFFF
background: secondary, // #A640FF
borderWidth: '1px',
borderStyle: 'solid',
borderColor: secondary // #A640FF
};

As simple as that: style your components. But as I mentioned above, you should be careful with color names. For instance, if you use a declarative way to describe an active color such as white (#FFFFFF) and apply it everywhere through your themes for different components properties (e.g. borders, icons, and text-colors), you will need to change it manually everywhere once you decide to change color palette value from white(#FFFFFF) to another color.

const secondaryTheme = {
color: white, // #FFFFFF

...other CSS declarations
};

Theming shades

For creating shades, we are using primary or secondary colors and changing only the alpha parameter. You can also use tertiary colors, yet remember the rule of simplicity. To make an editable state for the Tree-Element component, we used a simple color library, and you can do the same with pure CSS using an alpha parameter or using SCSS transparentize function.

Editable Theme

https://cdn-images-1.medium.com/max/1600/1*Wna1dfIjl_-35tKK34D5wg.png
// Styled Componentsconst opacity = {
primaryOpacity: 0.50,
secondaryOpacity: 0.25
}
const backgroundColor = color(primary)
.alpha(primaryOpacity)
.rgb()
.string();
const editableTheme = {
color: styles.active,
background: backgroundColor
};
// SCSS
$primaryOpacity: 0.5;
.selector {
background: transparentize($primaryForeground, $primaryOpacity);
}

This is how we are using colors in our design system.

We covered naming conventions, color palette, themes, and shades. Remember! To create a scalable design system, try to keep it simple.

I hope you found this article useful! If you have feedback, questions, let us know in the comments we are happy to answer! Feel free to reach me on Twitter.

Check out our next articles in the series, we will cover Typography, Layout, Spacing, Icons and more.

--

--