Tailwind CSS Color System: Customizing and Extending Palettes
Understanding Tailwind's Default Color System
Tailwind CSS provides a comprehensive, thoughtfully designed color system out of the box. Unlike many frameworks that offer a handful of generic colors, Tailwind ships with a complete color palette containing multiple shades for each hue, carefully calibrated for both light and dark themes.
The default color palette includes ten core colors: slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, and rose. Each color comes with 11 shades ranging from 50 (lightest) to 950 (darkest).
<!-- Using default Tailwind colors -->
<button class="bg-blue-500 text-white hover:bg-blue-600">
Default Blue Button
</button>
<div class="text-slate-700 dark:text-slate-300">
Text with dark mode support
</div>
The Anatomy of a Tailwind Color Scale
Each Tailwind color follows a consistent 50-950 scale with 11 steps:
/* Tailwind's blue palette structure */
--blue-50: #eff6ff; /* Very light tint */
--blue-100: #dbeafe;
--blue-200: #bfdbfe;
--blue-300: #93c5fd;
--blue-400: #60a5fa;
--blue-500: #3b82f6; /* Primary brand color (reference point) */
--blue-600: #2563eb;
--blue-700: #1d4ed8;
--blue-800: #1e40af;
--blue-900: #1e3a8a;
--blue-950: #172554; /* Very dark shade */
Why 50-950?
The numbering system is intentional:
- 50-100: Background tints, subtle highlights
- 200-300: Borders, dividers, disabled states
- 400-500: Primary interactive elements (buttons, links)
- 600-700: Hover/active states for 400-500
- 800-950: Text colors, dark backgrounds
This scale gives you enough granularity for accessible designs while remaining manageable.
Customizing Colors in tailwind.config.js
To customize your color palette, modify the theme.colors section in your Tailwind configuration:
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
// Add a custom brand color
brand: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
950: '#172554',
}
}
}
}
}
Replacing vs Extending
Tailwind offers two approaches:
1. Extend (recommended): Add to the default palette
theme: {
extend: {
colors: {
brand: { /* your colors */ }
}
}
}
// Result: You keep all default colors + your custom ones
2. Replace: Override the entire color system
theme: {
colors: {
brand: { /* your colors only */ }
}
}
// Result: Default colors are removed, only your colors remain
Creating a Complete 50-950 Scale
When building a custom color scale, you need to generate 11 shades that maintain consistent perceptual progression. Here are three approaches:
Method 1: Use an Online Palette Generator
Tools like Tailwind Color Shades Generator or Hypercolor can generate a full scale from a single base color.
Method 2: Use oklch() for Precision
Modern CSS's oklch() function makes it easy to create perceptually uniform scales:
// Calculate programmatically
function generatePalette(baseLightness, baseChroma, baseHue) {
return {
50: `oklch(${Math.min(baseLightness + 35, 98)}% ${baseChroma * 0.3} ${baseHue})`,
100: `oklch(${Math.min(baseLightness + 30, 95)}% ${baseChroma * 0.4} ${baseHue})`,
200: `oklch(${Math.min(baseLightness + 20, 90)}% ${baseChroma * 0.5} ${baseHue})`,
300: `oklch(${Math.min(baseLightness + 10, 80)}% ${baseChroma * 0.7} ${baseHue})`,
400: `oklch(${baseLightness + 5}% ${baseChroma * 0.85} ${baseHue})`,
500: `oklch(${baseLightness}% ${baseChroma} ${baseHue})`, // Reference
600: `oklch(${Math.max(baseLightness - 10, 20)}% ${baseChroma} ${baseHue})`,
700: `oklch(${Math.max(baseLightness - 20, 15)}% ${baseChroma} ${baseHue})`,
800: `oklch(${Math.max(baseLightness - 30, 10)}% ${baseChroma * 0.95} ${baseHue})`,
900: `oklch(${Math.max(baseLightness - 40, 8)}% ${baseChroma * 0.9} ${baseHue})`,
950: `oklch(${Math.max(baseLightness - 50, 5)}% ${baseChroma * 0.85} ${baseHue})`,
}
}
// Example: Generate a blue palette
const brandBlue = generatePalette(60, 0.2, 264)
Method 3: Manual Adjustment with Tools
Start with your brand's primary color (usually the 500 shade) and manually adjust:
// Start with your brand color
const brand = {
500: '#3b82f6', // Your primary brand color
}
// Then use a tool to generate surrounding shades
// that maintain visual harmony
Integrating with CSS Custom Properties
For maximum flexibility, especially with dark mode, use CSS variables:
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
// Reference CSS variables
brand: {
50: 'rgb(var(--color-brand-50) / <alpha-value>)',
100: 'rgb(var(--color-brand-100) / <alpha-value>)',
200: 'rgb(var(--color-brand-200) / <alpha-value>)',
300: 'rgb(var(--color-brand-300) / <alpha-value>)',
400: 'rgb(var(--color-brand-400) / <alpha-value>)',
500: 'rgb(var(--color-brand-500) / <alpha-value>)',
600: 'rgb(var(--color-brand-600) / <alpha-value>)',
700: 'rgb(var(--color-brand-700) / <alpha-value>)',
800: 'rgb(var(--color-brand-800) / <alpha-value>)',
900: 'rgb(var(--color-brand-900) / <alpha-value>)',
950: 'rgb(var(--color-brand-950) / <alpha-value>)',
}
}
}
}
}
Then define the actual values in your CSS:
:root {
--color-brand-50: 239, 246, 255;
--color-brand-100: 219, 234, 254;
--color-brand-200: 191, 219, 254;
--color-brand-300: 147, 197, 253;
--color-brand-400: 96, 165, 250;
--color-brand-500: 59, 130, 246;
--color-brand-600: 37, 99, 235;
--color-brand-700: 29, 78, 216;
--color-brand-800: 30, 64, 175;
--color-brand-900: 30, 58, 138;
--color-brand-950: 23, 37, 84;
}
[data-theme="dark"] {
--color-brand-50: 30, 58, 138; /* Swap light/dark */
--color-brand-100: 30, 64, 175;
/* ... rest of the palette */
}
The <alpha-value> placeholder is replaced by Tailwind when you use opacity modifiers like bg-brand-500/50.
Dark Mode Color Strategy
When designing for dark mode, simply inverting your light mode palette usually doesn't work. Instead, consider these strategies:
Strategy 1: Swap Light and Dark Shades
// tailwind.config.js
colors: {
surface: {
light: '#ffffff', // Light mode: white background
dark: '#0f172a', // Dark mode: dark background
},
text: {
light: '#0f172a', // Light mode: dark text
dark: '#f8fafc', // Dark mode: light text
}
}
Usage with class strategy:
<div class="bg-white dark:bg-slate-950 text-slate-900 dark:text-slate-50">
Content here
</div>
Strategy 2: Use Separate Palettes
colors: {
// Light mode palette
light: {
bg: '#ffffff',
surface: '#f8fafc',
text: '#0f172a',
},
// Dark mode palette
dark: {
bg: '#0f172a',
surface: '#1e293b',
text: '#f8fafc',
}
}
Strategy 3: CSS Variables with Dark Mode
:root {
--color-surface: 255, 255, 255;
--color-text: 15, 23, 42;
}
[data-theme="dark"] {
--color-surface: 15, 23, 42;
--color-text: 248, 250, 252;
}
// tailwind.config.js
colors: {
surface: 'rgb(var(--color-surface) / <alpha-value>)',
text: 'rgb(var(--color-text) / <alpha-value>)',
}
Practical Examples
Building a Button Component
<!-- Using your custom brand color -->
<button class="
bg-brand-500
hover:bg-brand-600
active:bg-brand-700
text-white
py-2 px-4
rounded-lg
transition-colors
">
Brand Button
</button>
<!-- Disabled state using lighter shade -->
<button disabled class="bg-brand-200 text-brand-500 cursor-not-allowed">
Disabled
</button>
Creating a Card with Subtle Borders
<div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 rounded-xl p-6">
<h2 class="text-slate-900 dark:text-slate-100 text-xl font-semibold">
Card Title
</h2>
<p class="text-slate-600 dark:text-slate-400 mt-2">
Card content with proper dark mode colors.
</p>
</div>
Common Pitfalls to Avoid
- Don't skip shades: Incomplete palettes (e.g., only 100, 500, 900) limit your design options
- Maintain contrast: Ensure your 500 shade has enough contrast against white for accessibility
- Test in dark mode: Colors that work in light mode may be invisible in dark mode
- Avoid too many colors: Stick to 2-3 main color families plus neutrals
- Use opacity modifiers:
bg-brand-500/10is better than creating separatebrand-50light shades
Related Tools
- Color Converter - Convert colors to different formats for Tailwind config
- Tailwind Play - Test your color configuration online