Skip to main content
Dublin Library

The Publishing Project

Using Design Tokens in CSS

 

Design tokens provide a way to create representations of design assets like colors, fonts, spacing, animations, assets, etc., for styling and building cross-platform user interfaces.

One of the challenges with cross-platform product development is that operating systems use different style properties and formats to represent the same data. For example, the following code represents the same colors on different platforms:

  • HEX (CSS): FCC821
  • RGB (CSS): rgb(252, 200, 33)
  • RGBA (CSS): rgba(252, 200, 33, 1)
  • LCH (CSS): lch(83.525%, 53.373%, 83.39%)
  • Octal (Android/Flutter): 77144041

Instead of using these individual properties, designers and engineers reference a token like color.palette.primary representing all four color codes. The color will always be the same regardless of the platform or programming language.

Organizations use these design tokens to create a single point of truth for design-related assets and to create a file that can be shared across the organization so that everyone, whether working on a website or app or a micro front end for an enterprise module can use the same design vocabulary and creating a standard look for all.

Creating the tokens #

There is no standard way to create design tokens. The Design Tokens Community Group is as close to an industry consensus as there currently is in this space and the Design Tokens Format Module community report is as close as a specification. That means that we'll have to select one of the current alternatives to create our tokens.

Style Dictionary #

Style Dictionary creates styles for multiple platforms from a single source document. It is also extensible enabling future customizations to work in the projects we are working on like inserting the converted tokens into a WordPress theme's theme.json file.

So, technically, we could build the design tokens by hand directly in CSS in a similar way to building CSS custom properties

The main reason why I chose Style Dictionary is that it's the only format supported by the PostCSS Design Tokens plugin.

To get a basic Style Dictionary example that we can then customize follow these steps.

Install Style Dictionary as a global Node module using the -g flag. This will make the style-dictionary command available on your shell.

npm install -g style-dictionary

Once you install style-dictionary:

  1. Create a directory where you will store the design tokens
  2. Switch to the directory
  3. Run style-dictionary's initialization command with complete as the parameter
  4. Install Node dependencies
mkdir styles #1
cd styles #2
style-dictionary init complete #3
npm install #4

These commands will generate the scaffold for style-dictionary along with examples of design tokens.

The result will look something like this. I've removed details about Android and iOS to make the layout cleaner and to concentrate on CSS design tokens.

.
├── LICENSE
├── README.md
├── StyleDictionary.podspec
├── android
├── assets
│   └── fonts
│       ├── MaterialIcons-Regular.eot
│       ├── MaterialIcons-Regular.ttf
│       ├── MaterialIcons-Regular.woff
│       ├── MaterialIcons-Regular.woff2
│       ├── OpenSans-Regular.ttf
│       └── Roboto-Regular.ttf
├── config.json
├── ios
├── package.json
└── tokens
    ├── asset
    │   └── font.json
    ├── color
    │   ├── background.json
    │   ├── base.json
    │   ├── border.json
    │   ├── brand.json
    │   ├── chart.json
    │   └── font.json
    ├── content
    │   └── icon.json
    ├── font.json
    ├── size
    │   ├── font.json
    │   ├── icon.json
    │   └── padding.json
    └── time.json

The style-dictionary init command will also generate a package.json file that we can use to install dependencies and run updates for the tokens.

Every time that we make changes we need to run npm run build to update the tokens.

I don't use any of the settings in the default Style Dictionary configuration so I created a custom configuration to create CSS Custom Properties (CSS variables) and SCSS properties. The custom configuration looks like this:

{
  "source": [
    "tokens/**/*.json"
  ],
  "platforms": {
    "css": {
      "transformGroup": "css",
      "buildPath": "build/css/",
      "files": [{
          "format": "css/variables",
          "destination": "variables.css"
      }]
    },
    "scss": {
      "transformGroup": "scss",
      "buildPath": "build/scss/",
      "files": [{
        "format": "scss/variables",
        "destination": "_variables.scss"
      }]
    }
  }
}

We can import the variables from either CSS or SCSS files.

The SCSS files use an underscore (_) to indicate it's a partial that should not generate a corresponding CSS file. See SASS Basics for an explanation.

Becoming familiar with Style Dictionary #

There is a style-dictionary playground where you can learn about the tool, create your tokens and convert them to the format that you need for your work.

You can continue working in the playground or move to crafting the tokens by hand when you feel comfortable enough to do so.

Consuming the tokens and creating the styles from them #

Once we have generated the tokens we need to figure out how to use them.

Since I'm already using PostCSS, Postcss design tokens plugin becomes the perfect tool to use.

As with many tools, we need Node and Gulp installed.

We first install the necessary plugins: gulp-postcss and postcss-design-tokens

npm install -D gulp-postcss \
@csstools/postcss-design-tokens

We then integrate the plugin into your PostCSS workflow. The example below shows a gulpfile.js Gulp configuration with only the tasks necessary to work with design tokens.

const postcss = require('gulp-postcss');
const postcssDesignTokens = require('@csstools/postcss-design-tokens');

gulp.task('css', function () {
const plugins = [
  postcssDesignTokens()
];

return gulp.src('./src/*.css')
  .pipe(postcss(plugins))
  .pipe(gulp.dest('.'));
});

The CSS task only includes the design tokens plugin, it is likely that you have more plugins, at least Autoprefixer) and that you will want to do additional processing on your stylesheet.

Once we're happy with the way Gulp works, we can incorportate the design tokesn into our design.

Assuming that our tokens.json is in the same directory as our CSS, we use the @design-tokens at-rule to tell PostCSS where they are located and what format they are in. Currently, the plugin will online accept Style Dictionary version 3 files.

We then use design-token with the token value expressed in dot notation.

We also take advantage of Style Dictionary built-in conversion tools like to rem to make the work easier.

@design-tokens url('./tokens.json') format('style-dictionary3');

.foo {
  color: design-token('color.background.primary');
  padding: design-token('size.spacing.small' to rem);
}

@media (min-width: design-token('viewport.medium')) {
  .foo {
    padding-bottom: design-token('size.spacing.medium-alias' to rem);
  }
}

The block will convert to the following CSS block.

.foo {
  color: #fff;
  padding: 1rem;
}

@media (min-width: 35rem) {
  .foo {
    padding-bottom: 1.125rem;
  }
}

This is just scratching the surface but it offers interesting new possibilities.

With Design Tokens we can now create a central repository for our company or project styles.

In theory, we could also transform the Design Tokens files into other formats like WordPress theme.json configuration file. We'll research this in a future post.

Edit on Github