Designing Tokens — What makes great design tokens, and how to build them (Part 3)

The Problems

In Part 1, we discussed and came up with some criterias for a good consumption friendly token system. In Part 2, we turned those requirements in an exact Consumption-friendly-format. In this post, we identify a few problems with the Consumption-friendly-format when it comes to maintenance.

Maintenance problem 1 — Typos

Because we are attaching the CSS property as plain string in our token object, it is easy to make a mistake. For example, in the following code, there is a typo in color.background.alt

const tokens = {
color: {
background: {
default: "background-color: #ffffff",
alt: "background-colour: #b2b2b2",
inverse: "background-color: #000000",
...
},
...
},
...
};

Maintenance Problem 2 — Documentation

We have comments over every token for intellisense. (See Part 1, Iteration 5 for details) But doing this manually is error prone especially when the code itself is updated. For example, in the above tokens:

const tokens = {
layout: {
zIndex: {
/** 1200 */
snackbar: "z-index: 1200",
/** 1400 */
spinner: "z-index: 1500",
...
},
...
},
...
};

Maintenance Problem 3— Inconsistency.

If we have a blue color that CAN be used as both text and background color, in the current setup, there’s no way to indicate that those two are suppose to be the same color, and it’s easy to make a mistake:

const tokens = {
color: {
background: {
interaction: "background-color: #0096e7", ...
},
text: {
interaction: "background-color: #0096e6", ...
},
...
},
...
};

Maintenance-friendly-format

What would be nice is if we could auto generate the Consumption-friendly-format tokens from a format that’s easy to maintain.(Lets refer to this as the Maintenance-friendly-format) for example:

const tokens = {
color: {
base: {
orange: { value: '#ff9b00' },
purple: { value: '#5f259f' },
blue: { value: '#0096e6' },
red: { value: '#ff0000' },
white: { value: '#ffffff' },
lightGray: { value: '#b2b2b2' },
gray: { value: '#999999' },
darkGray: { value: '#333333' },
black: { value: '#000000' },
},
text: {
brand1: { value: '{color.base.orange}' },
brand2: { value: '{color.base.purple}' },
interaction: { value: '{color.base.blue}' },
error: { value: '{color.base.red}' },
inverse: { value: '{color.base.white}' },
default: { value: '{color.base.darkGray}' },
},
background: {
brand1: { value: '{color.base.orange}' },
brand2: { value: '{color.base.purple}' },
interaction: { value: '{color.base.blue}' },
default: { value: '{color.base.white}' },
alt: { value: '#{color.base.lightGray}' },
inverse: { value: '{color.base.black}' },
},
icon: {
inverse: { value: '{color.base.white}' },
default: { value: '{color.base.gray}' },
interaction: { value: '{color.base.blue}' },
},
},
layout: {
media: {
tablet: { value: '640' },
desktop: { value: '940' },
largeDesktop: { value: '1200' },
},
zIndex: {
bottomlessPit: { value: '-9999' },
dropdown: { value: '200' },
sticky: { value: '400' },
popover: { value: '600' },
default: { value: '1' },
overlay: { value: '800' },
modal: { value: '1000' },
snackbar: { value: '1200' },
spinner: { value: '1500' },
overTheMoon: { value: '9999' },
},
size: {
font: {
sm1: { value: '12px' },
sm2: { value: '14px' },
sm3: { value: '16px' },
sm4: { value: '18px' },
lg1: { value: '24px' },
lg2: { value: '32px' },
lg3: { value: '40px' },
lg4: { value: '48px' },
},
},
},
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
David Xu

David Xu

Code monkey specializing in React.js