A Design Tokens Workflow (part 6)
Layers, referencing tokens in Style Dictionary
- Getting Started With Style Dictionary
- Outputting to Different Formats with Style Dictionary
- Beyond JSON: Exploring File Formats for Design Tokens
- Converting Tokens with Style Dictionary
- Organising Outputs with Style Dictionary
- Layers, referencing tokens in Style Dictionary – You are here
On This Page:
In previous articles, we explored how to create and generate design tokens using Style Dictionary. Now, we’ll build upon that foundation by setting up token layers in Style Dictionary, showing how to reference tokens across layers and generate outputs for better usability.
A brief explanation of Design Tokens layers
Design Token layers can be essential for creating a scalable and maintainable design system. They can help separate raw values from their contextual meanings. In separating tokens into different layers, such as base, semantic, and component tokens, we can better organise their purposes and usage while ensuring the system remains flexible and future-proof.
The most common layers used for Design Tokens in a Design System include base, semantic, and component tokens, each serve a unique role in your workflow.
- Base Tokens: These are the raw, literal values, such as
#bada55
for a green colour or1rem
for spacing. They form the foundation of your design system, with descriptive names that reflect their physical properties (e.g.,color-green-400
,spacing-small
). - Semantic Tokens: These tokens provide context and meaning to the base tokens. For example,
--note-color
might reference the base token--color-green-400
. Semantic tokens abstract intent, making them easier to use and apply consistently across a design system. - Component Tokens: These tokens define values specific to individual components, such as
--button-primary-bg
for a button’s background colour. Component tokens build upon semantic tokens to tailor the design system for particular use cases. While they play a crucial role in token workflows, we won’t explore them in detail today, focusing instead on base and semantic layers.
Separating tokens into layers provides flexibility and scalability. Semantic tokens allow users to work with meaningful names while base tokens remain stable and reusable. This separation can also support theming, where adjusting base tokens can create design variations without changes to semantic tokens.
While “base” and “semantic” are widely used terms, some teams prefer alternatives like “literal” or “raw” for base tokens and “contextual” for semantic tokens.
Regardless of your chosen terminology, maintaining clarity and consistency within your system is key.
For more details on Design Tokens layers you can read Naming Tokens in Design Systems from Nathan Curtis and Best Practices For Naming Design Tokens, Components And Variables from Cosima on Smashing Magazine
Setting Up Style Dictionary for Token Layers
To effectively separate token layers using Style Dictionary, we will organise our files and folders to reflect the layered structure we are aiming for. This setup allows us to maintain a clear distinction between the raw values and their contextual meanings while also enabling outputs that can meet various design and development goals.
Configuring Style Dictionary to Separate Base and Semantic Tokens
The first step to setting up token layers is to organise the token files into distinct folders for base and semantic tokens. This should make it easier to manage each layer independently.
Here’s an example of a simple folder structure:
To generate separate outputs for these layers, we’ll configure Style Dictionary to filter tokens by folder and output them to distinct files or directories. Below is an example configuration using Style Dictionary:
This configuration will build two separate outputs, one for the base tokens (build/base/tokens.css
) and another for the semantic tokens (build/semantic/tokens.css
).
Referencing Base Tokens in Semantic Tokens
Design Token layers can build upon other layers by referencing them in their definitions. Style Dictionary makes this simple with its {tokenPath} syntax. For example:
Base Tokens
Semantic Tokens
Using the configuration above this will resolve the {color-warning}
in the semantic tokens to a hardcoded value:
Base Tokens CSS
Semantic Tokens CSS
By default, Style Dictionary replaces the {color.red.400}
reference with its resolved value (#ff0000)
. This behaviour is intentional and ensures the output works even if references are not supported in the target environment.
Retaining Variable References in Outputs
If you want the semantic tokens to reference base tokens as CSS custom properties or Sass variables (for example), you need to enable the outputReferences
option in your Style Dictionary configuration:
The updated configuration file now looks like this:
With this updated configuration, the output will retain references:
Base Tokens CSS
Semantic Tokens CSS
Variable References vs. Hardcoded Values
When generating semantic tokens, you can decide whether to reference base tokens as variables or use hard coded values:
Variable References (--warning-color: var(--color-red-400);
)
Referencing base tokens as variables ensures that updates to base tokens cascade automatically to semantic tokens. This is particularly useful for theming or maintaining consistency across large systems. However, it requires including both base and semantic tokens in the final output, which can increase file size and dependencies.
Hardcoded Values (--warning-color: #ff0000
)
Hardcoding values in semantic tokens improves portability, as semantic tokens can be used independently of base tokens. However, it sacrifices flexibility, requiring updates in multiple places if a base value changes.
Choosing between these approaches depends on the goals of your design system. Variable references are ideal for systems where flexibility and theming are priorities, while hardcoded values can work better in simpler setups or when portability is key.
Generating Separate Files with Layered Outputs
To effectively manage layered Design Tokens, I think it's essential to generate separate output files that maintain the folder structure and filenames of the source tokens. This approach ensures that each file remains modular and easy to integrate into your workflows. Using Style Dictionary, we can achieve this while maintaining proper references in semantic tokens.
To combine the Design Token Layers with separate file outputs from the fifth article we need to change our configuration file a bit.
The code for this part of the series can be found here
First, we're going to make use of the glob
npm package to easily find all the .tokens
files in the folder.
We then need to create an array that processes each .tokens
file to generate corresponding .css
outputs, preserving the folder structure, filtering tokens by file, and enabling references for semantic tokens.
If you prefer hardcoded values and want to reduce the number of files, simply omit the outputReferences
option from the configuration.
This configuration generates .css
files for each .tokens
file found in the src/tokens directory, preserving the folder structure and applying specific logic for base and semantic tokens:
Directory Structure
For a src/tokens/
directory structured like this:
The output directory will look like this:
Base Token Output
Tokens in base files output hard coded values without references. For example:
tokens/base/color.tokens
build/base/color.css
Semantic Token Output
Tokens in semantic files reference base tokens using var(...)
. For example:
tokens/semantic/color.tokens
build/semantic/color.css
A Note on Warnings
Using this approach will likely have Style Dictionary in a bit of a spin and provide a warning in the terminal when the code is generated.
The warning indicates that some tokens in the output reference other tokens that were filtered out, potentially leading to broken references in the generated file. This happens because outputReferences: true
tries to preserve variable references (var(--token-name)
), but the referenced tokens are not included in the same output file.
I think you can safely ignore the warning if you’ve confirmed that the referenced tokens are included in other output files used alongside the semantic files, and the output meets your expectations.
However, if the semantic files need to function independently, you should either address the warning by including all necessary references in the same file or remove outputReferences: true to default to hardcoded values.
Component Tokens
While this article focuses on two layers of Design Tokens, it’s worth briefly introducing component tokens as the next layer in a Design Token hierarchy. Component tokens are values tailored to specific elements and components, such as buttons, cards, or headings, and are often built upon semantic tokens to ensure consistency with the broader Design System.
As an example, a button's background colour might use a semantic token like --primary-color
(if you set outputPreferences: true
like above):
Component tokens can provide flexibility for customisation while maintaining alignment with the Design System’s semantics. They enable teams to define granular, component-specific styles without duplicating design intent across multiple components.
This approach also makes it easier to manage component-level theming and variations. For instance, a --button-secondary-bg
token could reference the same semantic base but apply a slightly different tint for differentiation.
We’ll explore the role of component tokens, their setup, and practical applications in a future article, where they’ll be integrated as part of a cohesive Design Tokens workflow.
Layering Design Tokens with Style Dictionary is a practical way to create a clear and scalable Design System. By splitting tokens into layers like base and semantic, you can define them more clearly, adapt easily for theming, and make life simpler for design and development teams.