Implementing Design Tokens for Consistent UI Theming
Design tokens are the single source of truth for visual decisionsācolors, spacing, typography, shadows, and more. By storing these values in a centralized place (commonly CSS custom properties or a JSON file), you ensure consistency across components, pages, and even platforms (web, mobile, desktop). Changes to a token propagate automatically, reducing the risk of visual drift and making theme switches (like light/dark or brand-specific palettes) straightforward.
In a frontend codebase, start by defining tokens in the :root or a dedicated .css file using --token-name. Reference them throughout your stylesheets with var(--token-name). For dynamic theming, toggle a class on <html> or <body> to swap token values, or load a different token file via JavaScript. Pair this approach with a styleādictionary or tokenātransform tool if you need to export tokens to multiple formats (e.g., for iOS/Android). This method keeps CSS clean, improves maintainability, and scales well as your design system grows.
š»Source Code
/* tokens.css ā define all design tokens here */
:root {
/* Color palette */
--color-primary: #2563eb;
--color-primary-dark: #1d4ed8;
--color-background: #ffffff;
--color-background-dark: #111827;
--color-text: #111827;
--color-text-dark: #f9fafb;
/* Typography */
--font-sans: "Inter", system-ui, sans-serif;
--font-size-base: 1rem; /* 16px */
--font-size-lg: 1.125rem; /* 18px */
--font-size-xl: 1.25rem; /* 20px */
--line-height-base: 1.5;
--line-height-tight: 1.25;
/* Spacing (8px grid) */
--space-0: 0;
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
/* Border radius */
--radius-sm: 0.25rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
/* Shadow */
--shadow-sm: 0 1px 3px rgba(0,0,0,0.1);
--shadow-md: 0 4px 6px -1px rgba(0,0,0,0.1),
0 2px 4px -2px rgba(0,0,0,0.1);
}
/* Optional dark theme overrides */
.dark {
--color-background: #111827;
--color-background-dark: #0f172a;
--color-text: #f9fafb;
--color-text-dark: #ffffff;
}
/* Example usage in components */
.button {
background: var(--color-primary);
color: var(--color-text-dark);
border: none;
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-md);
font-size: var(--font-size-base);
line-height: var(--line-height-base);
box-shadow: var(--shadow-sm);
cursor: pointer;
}
.button:hover {
background: var(--color-primary-dark);
}
/* HTML example */
/*
<button class="button">Click me</button>
*/šRelated Snippets
Similar code snippets you might find interesting
Using Intersection Observer for Lazy Loading and Scroll-Based Animations
Leveraging Astro Islands for Interactive Content-Heavy Sites
Maintaining a Simple Global State Store in React Without Extra Libraries
š¬Comments (0)
šPlease login to post comments
No comments yet. Be the first to share your thoughts!
ā”Actions
Share this snippet:
š¤About the Author
manish
Active contributor
