Design Tokens
Design tokens are the smallest building blocks of a design system. They represent design decisions as data, making it easy to maintain consistency across platforms and products.
Yle Design System’s design tokens are based on Yle’s parent brand in terms of user interface design. The parent brand’s visual identity is black and white, minimalist, and fresh, enabling clear presentation of diverse content across Yle’s main services, such as the Yle service and Areena.
What are Design Tokens?
Design tokens capture the visual attributes of a design system—colors, typography, spacing, shadows, and more—as named entities. Instead of hardcoding values like #00b4c8 or 16px, we use semantic names like --yds-color-yle-turquoise-50 or --yds-spacing-16.
- Consistency: Semantic names ensure uniform styling across all products
- Maintainability: Update a token value once, and it propagates everywhere
- Theming: Switch between light and dark themes by swapping token sets
- Cross-platform: Same design decisions, different platform implementations
Token Categories
| Category | Description |
|---|---|
| Global Colors | Base color swatches with neutrals, brand colors, and other palettes |
| Theme Colors | Semantic tokens for UI: backgrounds, text, actions, and feedback |
| Spacing | Consistent spacing scale for margins, padding, and gaps |
| Border Radius | Corner rounding values for UI elements |
| Border | Border widths for UI elements |
| Shadows | Elevation and depth through box shadows |
| Typography | Font sizes, weights, and line heights |
| Transitions | Animation duration and easing values |
Using Tokens
CSS Variables
All tokens are available as CSS custom properties:
.button {
background-color: var(--yds-color-yle-turquoise-50);
padding: var(--yds-spacing-8) var(--yds-spacing-16);
border-radius: var(--yds-border-radius-medium);
transition: background-color var(--yds-transition-duration-s) var(--yds-transition-easing-default);
}
JavaScript Constants
Import tokens directly in JavaScript/TypeScript:
import { defaultTheme, spacing, radius } from '@yleisradio/yds-core';
const styles = {
backgroundColor: defaultTheme.BACKGROUND, // var(--yds-color-background, #ffffff)
padding: spacing.SPACING_16, // 16px
borderRadius: radius.MEDIUM, // 4px
};
Styled Components
Interpolate defaultTheme directly. Its values are custom property references, so the colors follow the active theme without any React context:
import styled from 'styled-components';
import { defaultTheme } from '@yleisradio/yds-core';
const Card = styled.div`
background-color: ${defaultTheme.BACKGROUND};
color: ${defaultTheme.TEXT_DEFAULT};
border: 1px solid ${defaultTheme.BORDER};
`;
Writing var(--yds-color-background) by hand works equally well. defaultTheme is typed, so it catches misspelled token names at compile time.
In 2.x these tokens came from props.theme.yds via YdsThemeProvider. That context was removed in 3.0. If the app keeps styled-components, see Using styled-components with YDS 3.0.
Theming
The design system supports multiple themes. Semantic color tokens automatically adapt when the theme changes:
- Light theme: Light backgrounds and dark texts.
- Dark theme: Dark backgrounds with light texts.
- Default theme: Default theme with variable color-scheme support to utilise both Light and Dark themes according to user preference
- Custom themes: Tietäjä and other product-specific themes, utilising either light or dark theme as a foundation
Using Theme Tokens
Use semantic theme tokens instead of base colors for UI elements. This ensures proper contrast and accessibility in both light and dark modes:
.card {
/* ✅ Do: Use theme tokens */
background-color: var(--yds-color-background);
color: var(--yds-color-default-text);
/* ❌ Don't: Use base colors for themed elements */
background-color: var(--yds-color-white);
}
Applying Themes
Import the theme CSS file and its variables are applied to :root automatically — no classes, no React needed:
/* Light theme applied to :root */
@import '@yleisradio/yds-core/tokens/build/css/_theme-default.css';
In React, use YdsThemeProvider from @yleisradio/yds-components-react for a subtree that needs a different theme than the document, or for a theme that changes in React:
import { YdsThemeProvider } from '@yleisradio/yds-components-react';
<YdsThemeProvider theme="dark">
<DarkSidebar />
</YdsThemeProvider>;
The theme prop accepts 'light', 'dark', 'default', or a custom theme object. Providers nest, so an inner one overrides the outer theme for its own subtree:
<YdsThemeProvider theme="default">
<MainContent />
<YdsThemeProvider theme="dark">
<DarkSidebar />
</YdsThemeProvider>
</YdsThemeProvider>
To automatically switch to dark based on the user's OS preference, use the prefers-color-scheme variant alongside the default:
@import '@yleisradio/yds-core/tokens/build/css/_theme-default.css';
@import '@yleisradio/yds-core/tokens/build/css/_theme-default-prefers-dark.css';
To force a specific theme on a subtree, import the themed variants and add the corresponding class:
@import '@yleisradio/yds-core/tokens/build/css/_theme-light.css';
@import '@yleisradio/yds-core/tokens/build/css/_theme-dark.css';
<div class="yds-theme-light">Light theme content</div>
<div class="yds-theme-dark">Dark theme content</div>
More information about theme setup can be found in the yds-core documentation.
Token Naming Convention
A design token is defined in the Figma Variables:
spacing/8: 8px
This gets converted to the following JSON:
{ "spacing": { "8": { "value": "8px" } } }
Is available in each platform format as:
CSS
var(--yds-spacing-8) // 8px
SCSS
$yds-spacing-8 // 8px
JavaScript
import { spacing } from '@yleisradio/yds-core';
spacing.SPACING_8; // 8px
For theme colors, token names are semantic (e.g., background, default-text) rather than descriptive of the color value itself, so they remain meaningful across themes.