Designing Hazel’s Accessible Color System (Part 2)

What happens when your simple color palette also needs to accommodate interaction states, sentiment, accessibility requirements, and more?

Francis Wu
4 min readMar 22, 2022

Note that this is part 2 of 2 about designing Hazel’s accessible color system. If you haven’t read part 1, here you go!

Eureka!

Whatever the solution, I had a feeling design tokens were going to offer some insight on how to systemize it all. And it just so happened that Figma’s 2021 Schema event was just around the corner and it included a presentation about design tokens in Asana’s design system.

Design Tokens in Asana’s Design System

The entire presentation’s worth a watch, but here’s the money shot:

Asana’s design tokens are organized by sentiment, usage, prominence, and interaction.

I felt as though they broke this case wide open.

Asana’s design tokens are made up of 4 semantic attributes.

Sentiment described the feeling the color was conveying. Options included default, success, warning, danger, upsell, selected, and beta.

Usage described the element upon which the color is being applied. Options included background, text, icon, and border.

Prominence described how much attention the color is drawing. Options included default, weak, medium, and strong.

Interaction described how the user is interacting with a colored element. Options included default, hover, active, and disabled.

Tweaking the Formula

Starting with my design system’s primary button, I quickly realized I couldn’t just apply Asana’s approach as-is.

What Asana sentiment for Hazel’s primary button? This button isn’t “selected”.

However, I was confident that it provided a solid framework that I could adapt by tweaking each attribute. I also reordered them to prioritize what the colors are being applied to.

Usage would be flattened to surface, content, and border. Content appear on surfaces and borders outline surfaces.

Sentiment would include neutral, primary, info, success, warning, and critical. Primary would cover interactive elements as well as elements that are “selected”. I might be stretching the meaning of “sentiment”, so I’m open to suggestions.

Prominence would include default, subdued, disabled, and muted, among others. Default would come to mean “maximum prominence”. This attribute became my catch-all drawer, with some regret that I’ll cover later.

Interaction wouldn’t change.

Injecting Meaning

It was also important that attribute values had meaningful and consistent definitions.

Some surface examples:

  • Default prominence meant the colors are adjusted to meet WCAG’s minimum text contrast requirements against their most likely content.
  • Subdued prominence meant the colors are adjusted to meet WCAG’s minimum non-text contrast requirements against their most likely content.
  • Muted prominence meant the colors are adjusted to match a 1.1:1 contrast ratio against the default surface color.

Content examples:

  • Default prominence meant the non-neutral colors are adjusted to match a 6.2:1 contrast ratio against the default surface color.
  • Subdued prominence meant the colors are adjusted to meet WCAG’s minimum text contrast requirements against their respective subdued surface colors.

Border examples:

  • Subdued prominence meant the colors are adjusted to meet WCAG’s minimum non-text contrast requirements against the default surface color.
  • Muted prominence meant the color’s opacity is set to 10%.

Interactions required no change in definition.

A Happy Side Effect

One of the challenges of designing white-label products is being handed brand assets that may not meet WCAG contrast requirements. This systematic approach to colors ensures your white-label product will be accessible.

Current Outcome

With Asana’s design token approach, I managed to go from a growing list of 206 colors to a relatively stable list of 119 colors.

From a growing list of 206 colors to a stable list of 119 colors with meaningful definitions

This represented ~40% reduction with a solution that scales!

Let’s go through a few examples.

Button Variants
Banner-Style and Dismiss-able Info Alert with Title and Actions
Success Text Fieldset with Trailing Icon Button
Default Toast with Action
Critical Tag with Leading Icon
Drop Zone Fieldset in Uploading State
Selected Mobile Collection Item

A Work in Progress

There are probably other ways to bake this cake but this is the first recipe I’ve been happy with.

Looking back, I’m not sure if “inversed” should be a “prominence” attribute. It might be more fitting if it was put under “usage” as an extension. For example, “surface-inversed” or “content-inversed”.

The “canvas” and “scrim” also appear to be misplaced under the “prominence” attribute. They’re both surfaces by definition so I’m not yet sure what to make of them. Perhaps they should just be outliers in this system? What do you think?

Whatever the case, I now have a sane approach to colors. I’m looking forward to applying this to a dark theme. But given how elevation in dark theme works differently from a light theme, I’m anticipating a few adjustments in how surface colors work.

--

--

Francis Wu

9 parts dad. 7 parts designer. 5 parts developer. 3 parts product manager. Some parts private.