System ColorDesigner InfoEngineer Info

With flying colors

Color is a strategic part of this design system, primarily arranged by someone with a color-deficiency with help along the way from expert resources and mathematic formulas. The efforts in defining the color system establish a disciplined collection of thoughtfully curated colors and ways to use them inclusively.

This page aims to outline what colors were chosen, how they were chosen, and why they were chosen.

Design Tokens

The color design tokens come in a few tiers which allow for theming between light and dark modes. The first tier of tokens (genitive, relating to each other) describe all of the colors we expect to use throughout the site. The second tier of tokens (locative, determined by placement) describe all of the components and properties we expect to use these tokens. Additionally, if design tokens outside of this system followed these patterns, they should also include namespacing (a prefix) to differentiate from other variables that may appear in the application.

Genitive Color Tokens

These tokens describe the general family that possess all the colors as human-readable names. They should not be applied directly to components or styles but instead referenced as the value for locative color tokens.

Accent color RGB values

These are applied by adding the token within an rgb() function.

TokenDescriptionValue
--color--greenThe green accent color25, 130, 120
--color--pinkThe pink accent color205, 40, 175
--color--blueThe blue accent color5, 106, 255

Accent color tokens

TokenDescriptionValue
--accent--defaultColorThe color to represent an accent. This may change at the application level to another color in this family.
--accent--everyoneColorThe color to represent all audiences.
--accent--designerColorThe color to represent a designer audience.
--accent--engineerColorThe color to represent an engineer audience.
--onAccent--defaultColorThe color expected to appear on the accent color when it is used as a background. This is always set to white regardless of theme.

Grayscale tokens

These are applied by adding the token as a lightness value within a formula for the hsl() function.

TokenDescriptionValue
--infragray--3Three exponential steps away from middle gray, toward white.
--infragray--2Two exponential steps away from middle gray, toward white.
--infragray--1One exponential step away from middle gray, toward white.
--ultragray--1One exponential step away from middle gray, toward black.
--ultragray--2Two exponential steps away from middle gray, toward black.
--ultragray--3Three exponential steps away from middle gray, toward black.

Locative Color Tokens

These tokens describe the place where the color is intented to be used. These are applied directly to CSS style properties of components. These colors will change value based on the current theme.

Boxes

This family of tokens describe containers for content.

TokenDescriptionValue
--box--backgroundColorDescribes the background color of the main content areas
--box--foregroundColorDescribes the foreground (text) color of the main content areas
--box--borderColorDescribes the border color of the main content areas
--boxLowContrast--backgroundColorDescribes the background color of the area which relate to the main areas with a slight contrast.
--boxLowContrast--foregroundColorDescribes the foreground (text) color of the area which relate to the main areas with a slight contrast.
--boxLowContrast--borderColorDescribes the border color of the area which relate to the main areas with a slight contrast.
--boxHighContrast--backgroundColorDescribes the background color of the area which relate to the main areas with a large contrast.
--boxHighContrast--foregroundColorDescribes the foreground (text) color of the area which relate to the main areas with a large contrast.
--boxHighContrast--borderColorDescribes the border color of the area which relate to the main areas with a large contrast.

Actions

This family descrbes colors for buttons and links. In some cases, the color on the component is either transparent or inherited from the parent.

TokenDescriptionValue
--action--backgroundColorDescribes the background color of the button or link.
--action--foregroundColorDescribes the foreground (text) color of the button or link.
--action--borderColorDescribes the border color of the button or link.
--action--outlineColorDescribes the outline color of the button or link for use in focused styles.
--actionHovered--backgroundColorDescribes the background color of the button or link when hovered.
--actionHovered--foregroundColorDescribes the foreground (text) color of the button or link when hovered.
--actionHovered--borderColorDescribes the border color of the button or link when hovered.

Controls

This family describes colors for form elements. In some cases, the color on the component is either transparent or inherited from the parent.

TokenDescriptionValue
--control--backgroundColorDescribes the background color of the control.
--control--foregroundColorDescribes the foreground (text) color of the control.
--control--borderColorDescribes the border color of the control.
--control--outlineColorDescribes the outline color of the control for use in focused styles.

Curation

Designer Info

The selection of colors in similar to the process outlined in Speccing Colors in Design Systems.

Beginning with layout colors; assuming everything is designed as grayscale. This is easy to visualize as wireframing with pencil and paper. This provides a perfect opportunity to identify the core user experience and lessen the concern about the personality of the interface. From there, accent colors were chosen to provide some charm and context.

Grays

A simple rule set here was to have three shades toward both ends of grayscale; 3 dark grays (including black) and 3 light grays (including white). This means there isn't a traditional material scale of color. Colors toward the middle of the scale tend to be less accessible, especially when mixing with more saturated colors.

It was all about contrast. Ether @Medium

The color steps of gray follow a logistic curve, meaning they increment exponentially from the middle gray. The formula to determine the level of gray is the following:

  • RGB: 255 / 1 + grayscalestep, result is the number for each color channel.
  • HSL: 100 / 1 + grayscalestep, result is the percentage of lightness (0% saturation).

Step 0 results in middle gray, each step either goes toward black (ultragray) or white (infragray). The grayscale value is where curation occurs as we can tune this to have more or less contrast between the grays. The higher the grayscale value, the more contrast between infragray and ultragray (which also results in less contrast between grays on the same side of the scale). You can see the effect of the value with the range control below.

Engineer Info

Calculating Gray in CSS

At first glance the formula for grayscale might look impossible in CSS however, we can use a trick outlined done in CSS typography found in A Responsive Guide to Type Sizing to create exponential scales.

From here, each area where we want to apply the actual gray, we use a calc function within hsl(). A simplier method of leveraging this is done within the article Calculating Color: Dynamic Color Theming with Pure CSS. This is where the logistic curve formula from above is applied, we use hsl() as only one value needs to be updated.

A drawback to this is window.getComputedStyle() cannot resolve this color.

Accent colors

Accent colors were chosen first by general hue then by accessibility measurements and finally applied to denote a user interaction or areas of interest. Many of the components that which can take an action are indicated using the accent color.

  • Green is meant to indicate the content is for all audiences.
  • Pink is meant to indicate the content is for designers.
  • Blue is meant to indicate the content is for engineers.

This is unique to the purposes of this site and its contents. For most of the site, a single accent color is chosen to enhance the user interface, except in areas where a specific audience is expected.

Engineer Info

The system could have leveraged a technique to compute the high contrast colors via CSS Custom Properties, the accent colors were curated so that each used as a background color would pair well with a white foreground color (versus a black foreground color).

Usability

In choosing colors, accessibility must be a priority. With the layout colors selected at opposite ends of the scale, this ensures that if a gray on one side appears as text on top of a gray on the other side. The text should pass accessibility standards (assuming the font size is appropriate). Accent colors are then chosen from a predetermined list and then reviewed for accessibility measurements and were considerate to not be based on cultural expectations.

WCAG accessible text

While there are now different standards between AA and AAA which also relate to font size, a general rule is to ensure a 4.5:1 contrast ratio between the background color and text. Throughout the site, this ratio is typically much higher. You can use the colorfield control below to test the ratio between a chosen text color and the current background color of the site. This should also update when changing the system color.

Engineer Info

The process in creating this functionality is outlined in the article Building your own color contrast checker which also explains the calculations involved to determine the ratio.

This isn't enough to simply select a high contrast between the background and text. Certain contrasts cause Irlen Syndrome which some people perceive the text to move on the page due to contrast sensitivity. The contrast between grayscale steps was adjusted to mitigate this.

Designer Info

The research explained in Designers should avoid pure black typography — but which dark gray should we use? provides insight that hsl(0, 0, 15%) was a contrast that reduced the effect of moving text. This value was a target when crafting the formula to step the grayscale.

Accent colors

The colorfield component above provides the Euclidean distance between the chosen color and a color from the list.

This tool was used to select the accent colors on the site that were close to desired hues. Admittedly, the accent colors selected for the site do not meet the 4.5:1 contrast ratio for both the light and dark themes and therefore you will find the majority of text is not given an accent color unless it is actionable. Actionable text styles and colors have been modified slightly to increase legibility to allow for accent colors to be used in these locations.

Engineer Info

The article Which Colors Look Good on Black and White? ends with a list of colors however, it would appear that these colors are only for black and white. Additionally, a post within the UX Stack Exchange also asks for a Background colour suitable for both black and white text with an answer providing a link to a much larger table of colors. That link is broken however, there is a backup. This is a json file with the referenced colors. Those colors are loaded into the colorfield component and the accent colors were chosen from this set.

Unlike many other systems, no color is selected to represent something good or bad. Different colors mean different things to different cultures. This could be rectified with localized color theming with a large effort for coverage or by choosing not including color as status. The system expects to use other patterns to help guide the user in understanding a meaning of state.