Skip to main content

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​

CategoryDescription
Global ColorsBase color swatches with neutrals, brand colors, and other palettes
Theme ColorsSemantic tokens for UI: backgrounds, text, actions, and feedback
SpacingConsistent spacing scale for margins, padding, and gaps
Border RadiusCorner rounding values for UI elements
BorderBorder widths for UI elements
ShadowsElevation and depth through box shadows
TypographyFont sizes, weights, and line heights
TransitionsAnimation 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.

note

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.