Theming
Build applications that support multiple color schemes. Learn design tokens, light/dark toggling, and multi-theme architecture with Tailwind CSS.
Design Tokens
Design tokens are the single source of truth for your visual language — colors, spacing, radii, and fonts. Instead of scattering hex codes everywhere, you define them once and reference them by name.
Token-Based Architecture
/* globals.css — Define your tokens */
@theme {
--color-primary: #6366f1;
--color-primary-hover: #4f46e5;
--color-secondary: #ec4899;
--color-background: #ffffff;
--color-foreground: #0a0a0a;
--color-muted: #737373;
--color-border: #e5e5e5;
--radius-sm: 0.375rem;
--radius-md: 0.5rem;
--radius-lg: 1rem;
}
/* Usage — semantic, readable, consistent */
<button className="bg-primary hover:bg-primary-hover
text-white rounded-md px-4 py-2">
Save Changes
</button> Why Tokens? If your designer changes the brand color from indigo to blue, you update one variable instead of searching through hundreds of files for
bg-indigo-500.Light / Dark Toggle
The simplest theming pattern: two color schemes (light and dark) switched via a class on the root element. This app uses this exact approach.
Dark Mode with CSS Variables
/* globals.css */
:root {
--color-background: #ffffff;
--color-foreground: #0a0a0a;
--color-card: #ffffff;
--color-border: #e5e5e5;
}
.dark {
--color-background: #0a0a0a;
--color-foreground: #fafafa;
--color-card: #171717;
--color-border: #262626;
}
/* Your components stay the same! */
<div className="bg-[var(--color-card)]
border-[var(--color-border)]
text-[var(--color-foreground)]">
Adapts automatically to theme
</div>Live Demo — These cards respond to your current theme:
Light Mode
Clean, bright surfaces
Dark Mode
Easy on the eyes at night
Multi-Theme Architecture
Need more than just light/dark? Use data-theme attributes to support unlimited color schemes — perfect for SaaS apps that let users pick their own theme.
Multiple Themes with data-theme
/* globals.css */
:root,
[data-theme="default"] {
--color-primary: #6366f1; /* Indigo */
--color-accent: #f59e0b;
}
[data-theme="ocean"] {
--color-primary: #0ea5e9; /* Sky blue */
--color-accent: #06b6d4;
}
[data-theme="forest"] {
--color-primary: #22c55e; /* Green */
--color-accent: #84cc16;
}
/* Toggle in React: */
<html data-theme="ocean">
{/* Everything inside uses ocean colors */}
</html>
/* All your components remain unchanged! */
<button className="bg-primary text-white">
I'm sky blue in ocean mode,
indigo in default mode,
and green in forest mode — automatically.
</button> The Architecture: Your components never reference specific colors like
bg-indigo-500. They only use semantic tokens like bg-primary. The CSS variables resolve the actual hex value based on which data-theme is active. This means zero component changes when adding a new theme.