Skip to content

Semantic Token Names

Benny Powers edited this page Feb 8, 2023 · 5 revisions

Note: specific values or token names in the document may be out of date by the time you read it.

Values vs. 'Crayon' Names vs. Semantic Names

Some Red Hat Design Tokens, refer directly to a specific CSS value, like a colour value:

--rh-color-red-500: #ee0000;

While others are aliased to a token which directly defines a colour.

--rh-color-brand-red-on-light: var(--rh-color-red-500, #ee0000);

In the case of colour, the direct value tokens are called "crayon" tokens, while the aliases are called "semantic" tokens

The same relationships can exist for length values:

--rh-border-width-lg: var(--rh-length-2xs, 3px);

Developing the Tokens

In our tokens's sources, these relationships are defined using aliases, which look like this (source):

color:
  icon:
    primary:
      on-light:
        $value: '{color.brand.red.on-light}'

Which in turn refers to this alias (source):

color:
  brand:
    red:
      on-light:
        $value: '{color.red.500}'
        $description: Brand red on light background

Which finally resolves to this hex value (source):

color:
  red:
    500:
      $value: '#ee0000'
      $description: Brand red (light theme)

Designers should be the primary voices in developing the tree of relationships between token names, aliases, and values.

When to Use Which Names

When designing workflows, pages, patterns, or elements in RHDS, designers should prefer to use semantic token names rather than directly referring to crayon names, and should never directly use values when a suitable token exists.

a {
  /* ❌ Don't do */
  color: #0066cc;
  /* ⚠️ Avoid */
  color: var(--rh-color-blue-400, #0066cc);
  /* ✅ Ideal */
  color: var(--rh-color-interactive-blue-darker, #0066cc);
}

Multiple aliases may exist for a given crayon value, as well. For example, and at the time of this writing, the blue tone #0066cc has the following aliases:

--rh-color-interactive-blue-darker: #0066cc;
--rh-context-light-color-focus: #0066cc;
--rh-context-light-color-text-link: #0066cc;
--rh-color-accent-base-on-light: #0066cc;
--rh-color-border-interactive-on-light: #0066cc;
--rh-color-blue-400: #0066cc;

Specifying Intent, not Pixel Values

When specifying CSS values like colours, fonts, or lengths, designers should be intentional about the meaning of the design token they prescribe.

Is this colour being used to indicate an interactive element? Specify --rh-color-interactive-blue-darker. Will it be used to draw a border around an interactive element? Specify --rh-color-border-interactive-on-light. It's important for designers to specify not just the values but also the semantics, since developers will not always be able to infer the designer's unstated intent from looking at the mockups or reading the design spec.

Further more, token values or alias linkages may change over time. Consider the case of the border around an interactive element. Say the designer specified the crayon value (or worse, the hex value), and the developer implemented it as such. Later, the decision is taken at a high level to change the underlying colour value of all interactive elements' borders from, let's say, blue to purple. In that case, our element's borders would remain blue, leading to a confusing and inconsistent user experience. The designers would now have to communicate the change, directly specifying the change in terms of colour values at every instance in the entire design system, and rely on developer discipline to catch them all.

Element Border All Other Borders
Before Blue Blue
After Blue Purple

Had the designer specified the semantic token name, automated tools like stylelint could update the entire design system in one command

stylelint --fix ./elements
Element Border All Other Borders
Before Blue Blue
After Purple Purple

When to Use Crayon Names

There are times when a cigar is just a cigar. When specifying colour variants, designers should continue to prescribe crayon names, but should not specify hex values:

✅ Do This:

The red variant of the alert element should use color.red.500 for its border

❌ Don't do this:

The red variant of the alert element should use #ee0000 for its border.

Benefits

By specifying semantic token names rather than values, designers can ensure that:

  • Their designs will express their intent for the user
  • Their designs will be highly themable
  • Their designs will be responsive to container sizes and colour contexts
  • The implementation of their designs will be resilient to changes in the token values

Designers should therefore

  • be careful to specify the most abstract token name available (i.e. the most highly aliased),
  • only specify lowest-level tokens (e.g. crayons or lengths) when they intend that specific value absent of any additional meaning, and
  • never directly specify a CSS value (like a hex, rgb(), or px length) when a suitable token exists.