How We Created an Accessible, Scalable Color Palette

A case study of how we launched a color palette across all platforms at Modern Health

Brian Cleveland
10 min readJun 2, 2023
A table of color values plotted on an X-Y axis to show their relative color contrast ratios (blue color group used as example)
A color table in Figma we use to help visualize color contrast at various steps

During the latter part of 2021, I reflected on the challenges we were facing at Modern Health. One recurring problem that stood out was our struggle to create new products with an unstructured color palette. This resulted in poor communication between designers and developers, an inconsistent product brand, and increasing accessibility problems.

The color palette we use today at Modern Health for all user-facing products follows these principles, as defined by our design system:

  1. Inclusivity: our palette provides easy ways to ensure our product uses accessible contrasts. Color groups and their steps have been chosen for UI familiarity and a clean look that reinforces the brand.
  2. Efficiency: our palette is diverse enough for our current and future product design, yet values are still predictable and constrained. This framework allows for color groups to evolve over time and enables the addition of future colors.
  3. Reusability: our palette is on-brand but versatile. There are very few one-offs that fall outside the palette. Our palette should be effective across any user-facing digital applications at Modern Health.

This article shares the process I followed to apply these principles to develop a more adaptable color palette that prioritizes accessibility and is built to scale into all of our future product design needs.

Overview

Problem to Solve

How can we maintain a color palette that is consistent with our growing product brand, communicated accurately between design and engineering, and be accessible across a broad spectrum of visual needs?

The design system vision: Clearly defined and easily understood documentation supporting a centralized architecture that empowers all product teams to launch products efficiently.

Web audit

A wide range of our existing digital product, showing a common set of colors
A “zoomed-out” view of the UI shows us which colors we used the most.

I ran our member-facing site through cssstats.com and found — unsurprisingly — that we had a lot of single-use color declarations and many references to hardcoded hex values. Despite the relatively limited palette in the existing user experience, there was a lot of repetition without clear guidance on how color should be applied.

Within text color declarations alone, we covered the rainbow and beyond.

Colors organically appeared in designs and code over time and — in an attempt to organize them — were given human-readable names. Using these names was unscalable; designer-developer communication couldn’t happen consistently, nor was there any way to know a color’s value by name alone.

I also ran color contrast accessibility audits using the WAVE Chrome extension. This informed us of low-contrast content in most core areas of the user experience. A low-contrast experience excludes users. It’s an easily solvable problem but isn’t always apparent to those without visual impairments or who are tasked with rapidly releasing features without a color framework on which to rely.

A WAVE accessibility audit showed a lot of contrast errors
A WAVE accessibility audit showed a lot of contrast errors

The first palette in the design system

My first pass at creating a color framework happened weeks after I started at Modern Health. I created a Foundation library in Figma that gathered the most common colors, reduced them down to a limited set, and applied a simple lightness scale and basic naming convention.

My first pass at a color palette used a pretty basic and hand-tweaked set of colors based on our brand palette
Here is the first color palette solution, which was okay for a while, but didn’t scale to our needs.

This Foundation palette was created by bucketing colors into color groups and reorganizing them around their lightness values (the L in HSL). The hex values were then hand-tweaked to give them a uniform look and to nudge them toward more accessible contrast levels. These colors were based on the brand guidelines.

It was clear that the way we named colors wouldn’t be the right way our product teams could communicate colors.

Even though we were making baby steps, we would soon hit a wall with how this framework would scale to our needs. We still lacked clarity on how colors should be applied consistently and we still weren’t putting accessible design first.

Why this framework didn’t work

The HSL (Hue Saturation Lightness) color model was the backbone of this original color framework, but anchoring around lightness and hand-tweaking isn’t the best way to scale, nor are we making accessible colors easy enough to apply as designers. However, in researching color models and exploring the work of other great design systems, I found many resources pointing to more human-friendly color models. After comparing and contrasting the ways these models could apply to digital design, I found an approach that was practical and applicable to our problem.

HSLuv is a modification to HSL that uses the same idea of Hue Saturation Lightness but in the CIELUV color model, which presents color lightness in a way that mimics real human perception. The difference, illustrated below, is most apparent when colors are placed in a lightness scale in equal steps.

(left) HSL colors evenly stepped in lightness will blur together in some ranges. (right) HSLuv, also in even steps, creates a more human-perceptible color range. You can see every step.
Two equal lightness values using HSL compared to two equal lightness values using HSLuv.
Two equal lightness values using HSL compared to two equal lightness values using HSLuv.

With a new color model and key issues to address, we also focused on envisioning the future of our product design. During this process, we experimented with color to add vibrancy and distinction to our features. Our goal was to pressure test this new color palette that could adapt to our evolving product vision while also complementing our existing designs.

Screenshots of our in-progress and visionary product design that pushed color use to new levels.
In-progress and visionary product design that pushed color use to new levels.

Goals & Approach

Our goals with this project, as adapted from the problem statement:
We want a centralized palette, accessible color contrast, clear naming conventions, and the ability to progressively improve and scale our colors within this framework.

Goal #1: Centralizing the palette

We wanted colors in the Foundation to be available in a library for all product UI in Figma and mirrored exactly in the coded foundation library. I started with the current Foundation palette, plotted as swatches on a lightness scale so we could observe the values in relation to each other.

I identified and created base colors (highlighted below) in each group and applied HSLuv color conversion, with the help of a Figma plugin, to create evenly distributed steps and form a broader, more cohesive palette. Unfortunately, hot pink didn’t make the cut.

A comparison of our old palette with our new updated palette, which used a color model that humans could better perceive.
Our existing palette (on the left) shows the relativity and gaps in the lightness scale. I was able to fill in the gaps with a properly scaled palette.

When the colors are desaturated, rows of color lightness can be clearly seen in the HSLuv color model. Even though the lightness values are similar in the original set, their perceived lightness is varied. This means that we could standardize color contrast in clear steps and that these steps would be consistent, regardless of hue.

When desaturating the new palette (removing color to make it monochrome) all colors had the same values
The old palette looks inconsistent because those lightness values weren’t normalized. In the HSLuv palette, every step has the exact same (perceived) lightness.

Goal #2: Making contrast accessibility easy

We wanted good color contrast to be easier to understand and apply, WCAG AAA compliant (7:1 contrast ratio) for most text, AA compliant for some actions and icons (4.5:1), and AA+ (3:1) for large text and non-necessary visual aids. Taking this approach would also open us up to new concepts such as theming (e.g. dark mode).

We can much more easily predict the color contrast ratio in this new model. Every row has the same normalized lightness, making contrast ratios the same, regardless of color pairings. We can combine colors of different lightness and different color groups and still guarantee consistent contrast ratios. This enabled easier ways to design contrast-compliant color themes.

A figure showing how colors could easily reach high contrast by merely counting steps
You can estimate the contrast ratio by counting the steps between lightness levels in the scales. In these examples, putting 3 steps between colors guarantees AA contrast.

Goal #3: Consistent naming conventions

We wanted color names to be human-readable, based on a consistent and predictable scale, and allow for adding new color steps and color groups. In normalizing these conventions, we wanted the communication between product partners to be frictionless.

A snippet of the new palette

We would use familiar names for color groups, removing ambiguity. At this point, we’ve entirely eliminated references like weepingWhaleBlue. The numeric scale was also changed to be between 0 and 100, which made communicating the color’s appearance easy, even when only reading the name. For example, the color blue-05 is a very light blue while blue-55, in the mid-range, would be more vibrant, neither dark nor light.

We also chose to make the steps of each color group consistent, but not necessarily equal steps of 10. Anchoring around this lightness scale gave us more ways to effectively combine colors in our products and made the lightest and darkest colors more useful overall.

A visual showing that the steps for each color group are not equal, but specifically chosen for their versatility

Goal #4: A framework built for scale

As we learned more about our ideal product brand, colors were designed to change safely over time. We also made migrating legacy designs to a new color system easier in both Figma and in code.

In addition to migrating the old palette to the new one, we were also looking toward the future. Given a more easy-to-use, accessible palette, we could now think in terms of theming components and layouts, e.g. dark mode.

Two versions of a user interface, one in a light mode and one in a dark mode
Theming components made easier with the new palette

Providing this framework—guided by clear standards and a consistent naming convention—also made it much easier to make changes and incorporate new colors (more on that in The Results below).

Writing Guidelines for Responsible Color Design

Clear documentation is of utmost importance when managing a design system. In writing concise and easily understood color usage guidelines, I chose to focus on two things:

  1. WCAG guidelines for color contrast
  2. Common UI colors

WCAG color contrast

We design with a minimum WCAG AA accessible ratio (4.5:1 minimum ratio) for all text, but our guidelines (as well as our coded library components) make sure that most text is AAA compliant (7:1 ratio). A significant part of the Modern Health experience — like most of the web — is written language, so providing designers with easy mechanisms for serving high-contrast designs was necessary.

We serve a large community and the design system should be fundamentally inclusive. Here are the overview guidelines for color contrast:

Guidelines for color contrast
An example of a UI element where all of the high contrast elements are described
As an example, here’s an InlineCallout component following the guidelines above

Common UI colors

In addition to contrast guidelines, we also provide references and general usage guidelines for colors. This allows our design team to creatively make use of our entire palette while keeping the core UX consistent.

Guidelines for using colors at Modern Health

The Results

Since introducing the new palette in Figma, we’ve also migrated all of our web applications to use the codified equivalent in our design system. It’s been so exciting to see features fully referencing color variables like color.blue-55 instead of a myriad of hardcoded hex values.

All of these changes, vetted by our entire design team, have greatly improved our accessibility goals, ensured better consistency in our designs, and elevated the overall user experience. As a result, our developer experience has also been enhanced, enabling us to launch products more efficiently than ever before.

Here’s an application example from our design system Storybook documentation site:

import { Button } from '@modernhealth/vital-components';
import { colors } from '@modernhealth/vital-foundation';

const StyledVitaButton = styled(Button)({
backgroundColor: colors.red55,
borderColor: colors.red55,
color: colors.white,
':hover': {
backgroundColor: colors.red40,
},
});

Future-proof

When the time came to make changes, we were well-prepared. The whole premise of a design system is to centralize and single-source assets, so when we determined that we needed a new color group, it was incredibly easy to make the transition.

This is how green was introduced into our libraries.

A screenshot of adding a new color to the system

Similarly, we found the need to update colors to better represent the tone of our products. Yellow, in particular, felt out of place with the rest of the palette. Again, it was a few simple adjustments and suddenly our entire yellow color palette was updated everywhere.

Next steps

We’re more confident than ever that our color palette reflects our modern product brand and supports our principles of inclusivity and usability. In the future, we hope to continue to push the boundaries of theming, color gradients, and more.

We are also exploring proper design tokens for foundational styles like color. Design tokens would make centralized code even easier to maintain as well as put more of the control in the hands of the design team.

An example of how we might use the new palette to create design tokens that would enable easier coding in the future

Because of the thoughtfulness that has gone into this color framework, any future changes and additions will be more straightforward than ever before. This minor investment has paid off multiple times already and I look forward to all of the other frameworks for UI design that we can adopt in the design system.

Huge thanks to my partners on our design team who vetted these ideas with me, my manager who pushed my work to higher quality, to my engineering partners who made this dream a technical reality, and to our product teams who spread the good word and adopted this system with grace. And special thanks to all of the influences, researchers, and giants upon whose shoulders I sit.

--

--

Brian Cleveland

Father x4, retro video game collector, and design systems nerd