We should have a comprehensive documentation of our token system which explains the basic concept and the architecture we're using.
Basics
Design tokens — or tokens, for short — are design decisions, translated into data. They’re ultimately a communication tool: a shared language between design and engineering for communicating detailed information about how to build user interfaces.
Tokens consist of values needed to construct and maintain a design system, such as spacing, color, typography, object styles, animation, and more. They can represent anything that has a design definition, like a color as a RGB value, an opacity as a number, or an animation ease as Bezier coordinates.[^1]
Tokens are categorised into 3 groups: core, semantic and component tokens. Each group has it's specific purpose and rules. The core and semantic layer are meant to be internal to the Design System, the component layer is intended to be used by the implementation. This enables introducing changes to the core and semantic layers without breaking changes in the component layer.
Core tokens
Core tokens are the most basic tokens and represent concrete values, for example yellow = #ffcc00 or size-16 = 16px.
Don't assign semantic names to core tokens. Do yellow = #ffcc00 instead of brand-color = #ffcc00. brand-color is a semantic name and belongs in the next group
Core tokens can reference each other in composite or derived tokens: sandgray = #050400 can be reused for a transparent variant with sandgray-alpha-50 = rgba(sandgray, 0.5)
Core tokens should not be aliased. When there's a definition for sandgray = #050400 there should not be another core token with the exact same value, e.g. othergray = sandgray or othergray = #050400. This would unnecessarily increase the number of tokens
Core tokens should not be referenced or used directly in any application since they represent static values that are intended to be referenced by either semantic or component tokens
Semantic tokens
Semantic tokens represent changes in design decisions across different environments, for example the body font-size that grows larger with increasing browser size. The semantic layer can also be seen as a mapping layer between the core and the component layer. It reassigns tokens to the correct values based on the current environment, for example styles for an external post themed page on a mobile device in dark mode.
Semantic tokens should be named around design concepts like brand-color or font-size curves (TODO: better define what design concepts are)
Example of a responsive font size token definition in the semantic layer, referencing three different core tokens:
Token
Mobile
Tablet
Desktop
font-curve-base
size-16
size-18
size-20
Semantic tokens can reference core tokens as well as other semantic tokens
Semantic tokens should not be referenced or used directly in any application since they represent changing values. In any given environment, a semantic token is never guaranteed to be the finally desired value since it could be referenced and overridden by another semantic token
Tokens from the semantic layer are intended to be implemented in an automated process
Semantic tokens should be grouped by environment: modes (light/dark), themes (post/subsidiary X/subsidiary Y), devices (mobile/tablet/desktop), channels (internal/external).
It should be possible to extend or reduce semantic groups or their environments and re-map values without introducing breaking changes to the system. This is only possible if implementations use an automated process to ship semantic tokens and never directly reference semantic tokens from within components
Component tokens
On the last layer, component tokens are tied directly to components (or utilities) and their properties.
Component tokens should be named according to the property of a component, for example button-padding-left = interactive-padding-left. The naming of properties should be as platform agnostic as possible (foreground-colour instead of just colour which would be CSS specific and not self explanatory in a token context since it could mean border colour, background colour or text colour).
Every component should have it's own set of tokens, component tokens should not be shared between components (see #3356)
Component tokens should reference semantic tokens if their value is expected to change based on the environment they are used in. If the value is static, component tokens can also reference core tokens directly
We should have a comprehensive documentation of our token system which explains the basic concept and the architecture we're using.
Basics
Design tokens — or tokens, for short — are design decisions, translated into data. They’re ultimately a communication tool: a shared language between design and engineering for communicating detailed information about how to build user interfaces.
Tokens consist of values needed to construct and maintain a design system, such as spacing, color, typography, object styles, animation, and more. They can represent anything that has a design definition, like a color as a RGB value, an opacity as a number, or an animation ease as Bezier coordinates.[^1]
Other resources:
Architecture
Tokens are categorised into 3 groups: core, semantic and component tokens. Each group has it's specific purpose and rules. The core and semantic layer are meant to be internal to the Design System, the component layer is intended to be used by the implementation. This enables introducing changes to the core and semantic layers without breaking changes in the component layer.
Core tokens
Core tokens are the most basic tokens and represent concrete values, for example
yellow = #ffcc00
orsize-16 = 16px
.yellow = #ffcc00
instead ofbrand-color = #ffcc00
.brand-color
is a semantic name and belongs in the next groupsandgray = #050400
can be reused for a transparent variant withsandgray-alpha-50 = rgba(sandgray, 0.5)
sandgray = #050400
there should not be another core token with the exact same value, e.g.othergray = sandgray
orothergray = #050400
. This would unnecessarily increase the number of tokensSemantic tokens
Semantic tokens represent changes in design decisions across different environments, for example the body font-size that grows larger with increasing browser size. The semantic layer can also be seen as a mapping layer between the core and the component layer. It reassigns tokens to the correct values based on the current environment, for example styles for an external post themed page on a mobile device in dark mode.
Semantic tokens should be named around design concepts like
brand-color
or font-size curves (TODO: better define what design concepts are)Semantic tokens can reference core tokens as well as other semantic tokens
Semantic tokens should not be referenced or used directly in any application since they represent changing values. In any given environment, a semantic token is never guaranteed to be the finally desired value since it could be referenced and overridden by another semantic token
Tokens from the semantic layer are intended to be implemented in an automated process
Semantic tokens should be grouped by environment: modes (light/dark), themes (post/subsidiary X/subsidiary Y), devices (mobile/tablet/desktop), channels (internal/external).
It should be possible to extend or reduce semantic groups or their environments and re-map values without introducing breaking changes to the system. This is only possible if implementations use an automated process to ship semantic tokens and never directly reference semantic tokens from within components
Component tokens
On the last layer, component tokens are tied directly to components (or utilities) and their properties.
button-padding-left = interactive-padding-left
. The naming of properties should be as platform agnostic as possible (foreground-colour
instead of justcolour
which would be CSS specific and not self explanatory in a token context since it could mean border colour, background colour or text colour).[^1]: Design tokens - Spectrum: https://spectrum.adobe.com/page/design-tokens/