Creating colour systems for design

Luke Finch

web development

A few years ago I overhauled the product’s design system from working with around 40 colours, to working with 170 at last count.

Handling all those colours is no mean feat, and I’m sure you’re wondering why we need ~170 colours in our system. Put simply, our colours weren’t working for us. There was disparity across designers, products and production code. We lacked enough variance to handle multiple states of a component, and went down multiple routes to try and combat this. Our colours often weren’t accessible to contrast standards, and Sassy solutions to meet standards were just downright ugly.

darken(‘orange’, 60%) - Ew!

For years, we tried here and there to make things work, but the scale of our product ecosystem often meant tweaks rarely happened and we had to grit our teeth and make do. Thankfully, with our whole company moving major titles onto a centralised design system, we had an opportunity to address these concerns.

Throughout this article I’ll walk you through my process of migrating from our old system to our new one.

For Starters: Establish some ground rules

What’s a system without rules? I believe a colour system needs to be three things.

Accessible AA compliance as a minimum standard. No excuses Understandable How and why you use colours should be clear to users of the system. If a new starter can’t pick it up and run with it on their first day it’s too complicated. Beautiful Because you won’t get Dribbble likes if it's ugly.

Start wide, and narrow down

You need to at least have an idea of what you need out of your colour system. Casually audit your landscape. Keep it broad, think about groups of colours. What are you using the colours for now? What may you need them for in the future? Have you already established meanings of colours? Do your users know what they mean, either consciously or subconsciously?

At The Sun, we use colours to section parts of our site. News is blue, Football is green, Showbiz is purple, and so on... They serve as an additional tool to aid navigation, and over time, becomes embedded in a user’s understanding of the site. We also needed semantic colours to communicate with users, red for errors, amber for warnings, blue for tooltips etc. Add in some neutral colours for your interface, and you should have an idea of what you need. Here’s what we ended up with: Neutrals - Greys used for interface components and text Brand - House colour used for primary communication and the default signpost Sections: News, Football, Sport, Showbiz, Fabulous, Lifestyle, Money, Tech, Travel, Motors Interactive blue - For buttons and inputs, tooltips, etc. Semantic red - for errors or destructive actions Semantic green - for success states, and affirmative actions Semantic amber - for warnings and alerts Social colours - Colours used for representing different social media brands

Step three: Scale up, name appropriately

For each of those groups, we decided on having ten shades in a scale. This may seem like a lot, and you may need fewer, but those shades give us coverage across multiple states and use cases. A button for example needs at least four colours for its states. It’s default state, when a user hovers, when a user clicks, and when that button is disabled. We also needed enough colours to handle dark themes. All the while making sure our colours were compliant to a AA standard. We decided to name steps on our scales in a method similar to IBM Carbon, and this naming convention carries throughout all of our design tokens. Colours get darker as the number gets bigger. 010 is almost white, 100 is almost black.

Neutral010
Neutral020
Neutral030
Neutral040
Neutral050
Neutral060
Neutral070
Neutral080
Neutral090
Neutral100

This naming convention gives us a standard to stick to if we need to add another colour group, and has wiggle room if we ever needed to add in a shade in between two existing colours. Establishing a standardised naming convention makes it easy for new designers and developers to move within a scale.

Understand your constraints

What does WCAG compliance mean? When it comes to colour, we’re usually referring to WCAG’s success criterions:

  • 1.4.3 Contrast (Minimum)

  • 1.4.6 Contrast (Enhanced)

  • 1.4.11 Non Text Contrast

I strongly recommend you read all of the WCAG 2.1 criteria thoroughly but to paraphrase.

For AA compliance:

  • All text, and images of text has a contrast ratio of at least 4.5:1 (Except for large text 3:1)

  • All Interactive elements have a contrast ratio of at least 3:1

  • All graphics required to understand the content have a contrast ratio of at least 3:1

For AAA compliance:

  • All text and images of text has a contrast ratio of at least 7:1 (Except for large text 4.5:1)

  • All interactive elements have a contrast ratio of at least 3:1

  • All graphics required to understand the content have a contrast ratio of at least 3:1

What’s a Contrast Ratio ?

Contrast Ratios determine the difference in relative luminance between two colours. To determine the contrast ratio WCAG provides the formula

L1 is the relative luminance of the lighter of the colors, and L2 is the relative luminance of the darker of the colors

And what’s a relative luminance?

Relative Luminance is a measure of how much light a colour emits. For colour spaces such as XYZ, Y refers to the relative luminance. To get the relative luminance from a linear RGB colour space

This equation requires you to convert your colour from a gamma-compressed RGB value to linear RGB.

sRGB gamma-compresses its colour space to store more data in the darker regions, where it is easier to determine differences in colour compared to the lighter regions. Because of this gamma-compression, doing vector math doesn’t work, so we need to uncompress them.

Woah, that ends up being a lot of maths! Don’t worry you can put away your TI-84, I’ve provided a Google Sheet that does all the conversions for you.

I’d also recommend a tool like Stark https://www.getstark.co/ as a plugin for your design tool of choice. This lets you check your contrast ratios on the fly! 🖤