Always Twisted

What Else Can We Do With Design Tokens?

Design Tokens are a solution in Design System that allow teams to define and use their design decisions across disciplines, codebases, and frameworks.

Simply put they hold a name or ‘key’ for what the design decision is called and a ‘value’ which will get generated or exposed where needed.

Design Tokens are generally stored in a ‘single source of truth’ where they’re defined in one place and everyone else will use that or what is exported from it to use.

As a front-end developer I hvae often created and stored Design Tokens in code. This is generally in a text based file format called json, but it is (or perhaps was) possible to use the more white-space strict text format yaml.

The Design Tokens Specification

Before talking about what else can we do with Design Tokens, let's look at what is expected as the bare minimum. This information is taken from the work that the Design Tokens Working Group have been working on in creating a specifcation for Design Tokens.

As mentioned, Design Tokens are typically defined in JSON format, and the files can be named with a .tokens.json or .tokens extension.

Design Tokens must include a $name and $value:

Code languagejson
{
"tokenName": {
"$value": "#BADA55"
}
}

Design Tokens must also include a $type. Applying a type allows tools to interpret the tokens $value accordingly. You can apply the $type per Design Token but you can also simplify this by applying ot at a group level.

Example showing $type being applied per token:

Code languagejson
{
"primary": {
"$value": "#BADA55",
"$type": "color"
},
"secondary": {
"$value": "#C0FFEE",
"$type": "color"
}
}

Example showing $type being applied per group:

Code languagejson
{
"colors": {
"$type": "color",
"primary": {
"$value": "#BADA55"
},
"secondary": {
"$value": "#C0FFEE"
}
}
}

Design Tokens can hold more design decisions than colour so the standard defines various token types, including colordimensionfontWeightdurationfontFamilynumber and cubicBezier.

Code languagejson
{
"small": {
"$value": ".25rem",
"$type": "dimension"
},
"bold": {
"$value": 700,
"$type": "fontWeight"
},
"slow": {
"$value": "350ms",
"$type": "duration"
},
"mono": {
"$value": "Consolas",
"$type": "fontFamily"
},
"line-height-normal": {
"$value": 1.5,
"$type": "number"
},
"easing": {
"$value": [0, 0, 0.5, 1],
"$type": "cubicBezier"
}
}

Design Tokens can also, optionally, include a description that can help explain it's purpose:

Code languagejson
{
"warning": {
"$value": "#FFF3CD",
"$type": "color",
"$description": "Use this colour for warning states"
}
}

Can we do more?

Way back in 2019 I first read about the idea of adding meta information to your design tokens .json objects from Christiano in their a qrticle – Design Tokens beyond colors, typography, and spacing - the idea of meta information as part of a Design Token is also part of the proposed specification which states its use can help interoperability between tools and that we should restrict to information that is not necessarily vital to the understanding of the Design Token.

When I was helping Springer Nature revitalise their Design System efforts I took time to create and integrate Design Tokens into their existing code base.

As well as the $key, $value, and $type I also introduced meta information that assisted in the creating of documentation as well as specifying what syntax the tokens got generated to.

Below is an example of json that I worked on as part of the Design Tokens implementation in Springer Nature's Design System - Elements.

Code languagejson
"color": {
"primary": {
"name": "primary",
"value": "{color.brand.500}",
"type": "color",
"description": "The primary brand colour used for the website accents",
"category": "color",
"meta": {
"public": true,
"deprecated": false,
"documented": true,
"experimental": false,
"SassVariable": true,
"themeable": true,
"CSSCustomProperty": false
}
}
}

Using this example, let's pick this apart to see what this meta information was for and how it was utilised.

public

This was used to show or hide certain Design Tokens, or groups of, from being displayed on the documentation site. Why -- because we were trying to have folks use the 'semantic' design decisions rather than the lower level 'raw' base layer design tokens

{% if tokens.meta.public %} // All the code for documenting the token {% endif %}

deprecated

Can be used to make your documentation site add a small 'banner' or note to the tokens documentation to state that teams should not use this going forward.

In nunjucks it could look something like this:

{% if tokens.meta.deprecated %} <div class="ds-docs-message ds-docs-message--deprecated">     This token is deprecated. Please update to the latest version. </div> {% endif %}

We can also set replacements with it. We can also use this when generating pre-proccesor code like Sass to include a @warn rule to show folks it's being deprecated.

In Style Dictionary we can register a new format to show the deprecation as @warn rule.

Code languagejs
StyleDictionary.registerFormat({
name: 'scss/deprecated-warnings',
formatter: ({ dictionary }) => {
return dictionary.allProperties
.map(token => token.attributes?.deprecated ? `@warn "${token.name.replace('.', '-')} is deprecated. Please update it.";` : '')
.join('\n');
}
});

Which would output Sass to something like this

Code languagescss
@warn "color-primary is deprecated. Please update it.";
$color-primary: #BADA55;

experimental

The initial work on moving Springer Natures Design System forward with a new version of Elements meant, at times, there would be tokens that may or may not be used in the end - this led to creating a boolean key/value pair to, again, create a 'banner' in the documentation.

Similar to the deprecated meta information - we can use something like Nunjucks to determine if the an additional message is needed if the token is experimental.

{% if tokens.meta.experimental %} <div class="ds-docs-message ds-docs-message--experimental">     This token is experimental. Please update to the latest version. </div> {% endif %}

SassVariable

This was used to both generate the Sass variable so that it can be used and also display the Sass variable in the documentation.

themeable

When creating code from the design tokens - this would add !default. This would be as part of generating the code needed, in Style Dictionary we would have a registered format similar to this.

Code languagejs
StyleDictionary.registerFormat({
name: 'scss/themeable-defaults',
formatter: ({ dictionary }) => {
return dictionary.allProperties
.map(token => {
const value = `$${token.name.replace('.', '-')}: ${token.value}`;
return token.attributes?.themeable ? `${value} !default;` : `${value};`;
})
.join('\n');
}
});

This would generate something like this.

Code languagescss
$color-primary: #BADA55 !default;

CSSCustomProperty

Similarly, this was used to generate the associated CSS custom property and also display it in the documentation

Wrapping Up

Design Tokens are an essential part of Design Systems, by providing a way to develop a shared language it helps to close "the gap" between design and development.

As I have found in my consultancy work, adding layers of meta information can help with documenting, maintaining, and evolving the Design Tokens of a Design System over time.

Ultimately, Design Tokens can be more than storing values. They can be a way to create a cohesive, adaptable, future-proof design framework that grows with your project.

Struggling to decide how to name your design tokens consistently across your system?

I can guide you in creating a naming convention that’s intuitive and consistent.

get in touch!