CSS Design Tokens — Define Spacing, Colors, and Typography with Custom Properties
CSS design tokens store reusable values as custom properties (CSS variables). Learn how to define rem-based spacing and type scales, organize tokens by category, and share...
Use the tool
Pixel to REM Converter
Convert px to rem, em, and percent — and vice versa. Configurable root font size. Bulk conversion mode for entire stylesheets.
Design tokens are named values that store the visual design decisions for your system — colors, spacing, typography, shadows — as CSS custom properties that can be shared across components.
Convert px values to rem with the PX to REM Converter.
Defining tokens as CSS custom properties
/* tokens.css */
:root {
/* ===== Color tokens ===== */
--color-brand-primary: #2563eb;
--color-brand-primary-hover: #1d4ed8;
--color-text-primary: #111827;
--color-text-secondary: #6b7280;
--color-text-disabled: #9ca3af;
--color-bg-primary: #ffffff;
--color-bg-secondary: #f9fafb;
--color-border: #e5e7eb;
--color-error: #ef4444;
--color-success: #22c55e;
/* ===== Spacing tokens (rem-based 4px grid) ===== */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-5: 1.25rem; /* 20px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
--space-10: 2.5rem; /* 40px */
--space-12: 3rem; /* 48px */
--space-16: 4rem; /* 64px */
--space-20: 5rem; /* 80px */
--space-24: 6rem; /* 96px */
/* ===== Typography tokens ===== */
--font-sans: 'Inter', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', monospace;
--text-xs: 0.75rem; /* 12px */
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
--text-2xl: 1.5rem; /* 24px */
--text-3xl: 1.875rem; /* 30px */
--text-4xl: 2.25rem; /* 36px */
--leading-tight: 1.25;
--leading-snug: 1.375;
--leading-normal: 1.5;
--leading-relaxed: 1.625;
--tracking-tight: -0.025em;
--tracking-normal: 0em;
--tracking-wide: 0.025em;
/* ===== Shadow tokens ===== */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
/* ===== Border radius tokens ===== */
--radius-sm: 0.25rem;
--radius-md: 0.375rem;
--radius-lg: 0.5rem;
--radius-xl: 0.75rem;
--radius-full: 9999px;
/* ===== Transition tokens ===== */
--transition-fast: 150ms ease;
--transition-base: 200ms ease;
--transition-slow: 300ms ease;
}
Using tokens in components
/* button.css */
.btn {
padding: var(--space-2) var(--space-4);
font-size: var(--text-sm);
font-weight: 500;
line-height: var(--leading-tight);
border-radius: var(--radius-md);
transition: background-color var(--transition-fast);
}
.btn-primary {
background: var(--color-brand-primary);
color: white;
border: 1px solid transparent;
}
.btn-primary:hover {
background: var(--color-brand-primary-hover);
}
/* card.css */
.card {
padding: var(--space-6);
background: var(--color-bg-primary);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-sm);
}
Dark mode with tokens
/* Light mode (default): */
:root {
--color-text: #111827;
--color-bg: #ffffff;
--color-surface: #f9fafb;
--color-border: #e5e7eb;
}
/* Dark mode: override tokens only */
@media (prefers-color-scheme: dark) {
:root {
--color-text: #f9fafb;
--color-bg: #111827;
--color-surface: #1f2937;
--color-border: #374151;
}
}
/* All components using these tokens automatically switch — no other changes needed */
Share tokens between CSS and JavaScript
// tokens.js — single source of truth
export const tokens = {
space: {
1: '0.25rem', // 4px
2: '0.5rem', // 8px
4: '1rem', // 16px
8: '2rem', // 32px
},
color: {
brandPrimary: '#2563eb',
textPrimary: '#111827',
},
text: {
sm: '0.875rem',
base: '1rem',
lg: '1.125rem',
},
};
// Generate CSS custom properties:
export function generateCSSTokens(tokens, prefix = '') {
const lines = [];
for (const [key, value] of Object.entries(tokens)) {
if (typeof value === 'object') {
lines.push(...generateCSSTokens(value, `${prefix}${key}-`));
} else {
lines.push(`--${prefix}${key}: ${value};`);
}
}
return lines;
}
// Output: ["--space-1: 0.25rem;", "--color-brandPrimary: #2563eb;", ...]
Related tools
- PX to REM Converter — convert px spacing to rem
- Color Picker — choose brand colors
- CSS Grid Generator — use tokens in grid layouts
Related posts
- Fluid Typography with CSS clamp() — Scale Fonts Without Media Queries — CSS clamp() creates fluid typography that scales smoothly between minimum and ma…
- CSS Units Guide — px, em, rem, vw, vh, and When to Use Each — CSS has absolute units (px), relative to font-size (em, rem), viewport units (vw…
- Font Size Accessibility — Minimum Sizes, User Zoom, and WCAG Requirements — WCAG 2.1 doesn't mandate a specific minimum font size, but best practice is 16px…
- PX to REM Conversion — Formula, Table, and CSS Custom Properties — Convert pixel values to rem using the formula rem = px / base-font-size. Include…
- REM-Based Typography — Scalable Font Sizes with rem Units — Using rem for font sizes creates accessible, scalable typography. Text inherits …
Related tool
Pixel to REM Converter
Convert px to rem, em, and percent — and vice versa. Configurable root font size. Bulk conversion mode for entire stylesheets.
Written by Mian Ali Khalid. Part of the Frontend & Design pillar.