We use cookies to enhance your experience on the site
CodeWorlds

Design Tokens and Systematic CSS - Cosmic Design Code

Pilot, imagine that every ship in the galactic fleet uses exactly the same status colors, the same spacing between panels, and the same typography on monitors. This is no coincidence -- it's a design system. In the frontend world, the equivalent is design tokens -- a central source of truth for all visual values in the application.

What are Design Tokens?

Design tokens are named values representing design decisions: colors, spacing, font sizes, shadows, border radii. Instead of scattering magic numbers throughout the code, you define them in one place:

1// tokens.js -- central source of truth
2const tokens = {
3  colors: {
4    primary: '#7c4dff',
5    primaryLight: '#b388ff',
6    primaryDark: '#651fff',
7    success: '#00e676',
8    warning: '#ffa726',
9    danger: '#f44336',
10    bgDark: '#0a0a2e',
11    bgSurface: '#1a1a4e',
12    textPrimary: '#e0e0e0',
13    textMuted: '#9e9e9e',
14    border: '#3949ab',
15  },
16  spacing: {
17    xs: '4px',
18    sm: '8px',
19    md: '16px',
20    lg: '24px',
21    xl: '32px',
22    xxl: '48px',
23  },
24  fontSize: {
25    xs: '12px',
26    sm: '14px',
27    md: '16px',
28    lg: '20px',
29    xl: '28px',
30    xxl: '36px',
31  },
32  borderRadius: {
33    sm: '4px',
34    md: '8px',
35    lg: '12px',
36    xl: '20px',
37    full: '9999px',
38  },
39  shadows: {
40    sm: '0 2px 4px rgba(0,0,0,0.1)',
41    md: '0 4px 12px rgba(0,0,0,0.2)',
42    lg: '0 8px 24px rgba(0,0,0,0.3)',
43    glow: '0 0 20px rgba(124,77,255,0.3)',
44  },
45};

Using tokens in components

Once you have tokens defined, you use them instead of direct values:

1import { tokens } from './tokens';
2
3// In inline styles
4function Card({ children }) {
5  return (
6    <div style={{
7      background: tokens.colors.bgSurface,
8      padding: tokens.spacing.lg,
9      borderRadius: tokens.borderRadius.lg,
10      border: `1px solid ${tokens.colors.border}`,
11    }}>
12      {children}
13    </div>
14  );
15}
1// In styled-components
2const Card = styled.div`
3  background: ${tokens.colors.bgSurface};
4  padding: ${tokens.spacing.lg};
5  border-radius: ${tokens.borderRadius.lg};
6  border: 1px solid ${tokens.colors.border};
7`;

Tokens as CSS Variables

The best approach is to combine JavaScript tokens with CSS Variables -- you define tokens in JS (easy to manage) and pass them to CSS as variables (efficient rendering):

1function applyTokens(tokens) {
2  const vars = {};
3  vars['--color-primary'] = tokens.colors.primary;
4  vars['--color-bg'] = tokens.colors.bgDark;
5  vars['--color-surface'] = tokens.colors.bgSurface;
6  vars['--color-text'] = tokens.colors.textPrimary;
7  vars['--spacing-md'] = tokens.spacing.md;
8  vars['--spacing-lg'] = tokens.spacing.lg;
9  vars['--radius-lg'] = tokens.borderRadius.lg;
10  return vars;
11}
12
13function App() {
14  return (
15    <div style={applyTokens(tokens)} className="app">
16      {/* CSS uses var(--color-primary) etc. */}
17    </div>
18  );
19}

Consistent color system

A good color system has structure:

1const colorSystem = {
2  // Base colors
3  blue: { 50: '#e3f2fd', 100: '#bbdefb', 500: '#2196f3', 900: '#0d47a1' },
4  purple: { 50: '#f3e5f5', 100: '#e1bee7', 500: '#9c27b0', 900: '#4a148c' },
5
6  // Semantic colors (used in code)
7  primary: 'var(--blue-500)',
8  success: 'var(--green-500)',
9  warning: 'var(--orange-500)',
10  danger: 'var(--red-500)',
11
12  // Surface colors
13  background: '#0a0a2e',
14  surface: '#1a1a4e',
15  surfaceHover: '#2a2a5e',
16};

Semantic colors (primary, success, danger) are separated from base colors (blue-500, red-400). This way, changing the theme is just a mapping change, not searching through the entire codebase.

Spacing system

Spacing based on a scale -- each next value is a multiple of the base:

1// 4px scale (Tailwind-style)
2const spacing = {
3  0: '0px',
4  1: '4px',
5  2: '8px',
6  3: '12px',
7  4: '16px',
8  5: '20px',
9  6: '24px',
10  8: '32px',
11  10: '40px',
12  12: '48px',
13  16: '64px',
14};

Using a scale instead of arbitrary values guarantees visual consistency -- elements on the screen are evenly spaced, giving a professional look.

Typography as a system

1const typography = {
2  fontFamily: {
3    sans: "'Inter', 'Segoe UI', sans-serif",
4    mono: "'Fira Code', monospace",
5  },
6  fontSize: {
7    xs: ['12px', { lineHeight: '16px' }],
8    sm: ['14px', { lineHeight: '20px' }],
9    base: ['16px', { lineHeight: '24px' }],
10    lg: ['20px', { lineHeight: '28px' }],
11    xl: ['28px', { lineHeight: '36px' }],
12    '2xl': ['36px', { lineHeight: '44px' }],
13  },
14  fontWeight: {
15    normal: 400,
16    medium: 500,
17    semibold: 600,
18    bold: 700,
19  },
20};

Each font size has an assigned line height -- this eliminates typographic chaos.

Token Composition -- composing tokens

An advanced pattern is token composition -- creating more specific tokens from base ones:

1// Base tokens (primitive)
2const primitives = {
3  blue500: '#7c4dff',
4  blue300: '#b388ff',
5  green500: '#00e676',
6  red500: '#f44336',
7  gray900: '#0a0a2e',
8  gray800: '#1a1a4e',
9  gray100: '#e0e0e0',
10  gray400: '#9e9e9e',
11};
12
13// Semantic tokens (composed from base)
14const semantic = {
15  colorPrimary: primitives.blue500,
16  colorPrimaryLight: primitives.blue300,
17  colorSuccess: primitives.green500,
18  colorDanger: primitives.red500,
19  colorBackground: primitives.gray900,
20  colorSurface: primitives.gray800,
21  colorText: primitives.gray100,
22  colorTextMuted: primitives.gray400,
23};
24
25// Component tokens (composed from semantic)
26const components = {
27  buttonPrimaryBg: semantic.colorPrimary,
28  buttonPrimaryText: '#ffffff',
29  buttonDangerBg: semantic.colorDanger,
30  cardBg: semantic.colorSurface,
31  cardBorder: primitives.blue500 + '40',
32};

Three layers: base (values) -> semantic (meaning) -> component (usage). Changing a single base token cascades updates everywhere.

Style Dictionary -- automating tokens

In large projects, tokens are stored in JSON format and automatically generated for different platforms using the Style Dictionary tool:

1{
2  "color": {
3    "primary": { "value": "#7c4dff" },
4    "success": { "value": "#00e676" },
5    "background": { "value": "#0a0a2e" }
6  },
7  "spacing": {
8    "sm": { "value": "8px" },
9    "md": { "value": "16px" },
10    "lg": { "value": "24px" }
11  }
12}

Style Dictionary generates from this:

  • CSS Variables -- for web applications
  • JavaScript/TypeScript -- for React
  • Swift/Kotlin -- for mobile applications

One source of truth, multiple output formats.

Automating consistency

Creating a

TokenPreview
component helps control the entire system:

1function TokenPreview({ tokens }) {
2  return (
3    <div>
4      <h2>Colors</h2>
5      {Object.entries(tokens.colors).map(([name, value]) => (
6        <div key={name} style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
7          <div style={{ width: 40, height: 40, background: value, borderRadius: 8 }} />
8          <span>{name}: {value}</span>
9        </div>
10      ))}
11
12      <h2>Spacing</h2>
13      {Object.entries(tokens.spacing).map(([name, value]) => (
14        <div key={name} style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
15          <div style={{ width: value, height: 16, background: '#7c4dff' }} />
16          <span>{name}: {value}</span>
17        </div>
18      ))}
19    </div>
20  );
21}

When to use design tokens?

  • Any project larger than a landing page -- tokens save time in the long run
  • Team collaboration -- every developer uses the same values
  • Multiple themes -- changing one object changes the entire appearance
  • Cross-platform consistency -- Style Dictionary generates tokens for React, React Native, iOS, Android
  • Token composition -- three layers (base -> semantic -> component) give full control
Go to CodeWorlds