Tailwind Shade Generator: Custom Color Scales Made Easy
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://colorfyi.com/iframe/entity//" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://colorfyi.com/entity//
Add a dynamic SVG badge to your README or docs.
[](https://colorfyi.com/entity//)
Use the native HTML custom element.
Tailwind CSS ships with a carefully crafted color palette: 22 hues, each with 11 shades from 50 to 950. It covers the vast majority of use cases โ but the moment you need to use your brand's specific blue, or a purple that matches your company logo exactly, the built-in palette is not enough.
This is where a shade generator becomes essential. You provide one color โ your brand primary, an accent, a semantic color โ and the generator outputs a complete 50-to-950 scale, formatted exactly as a Tailwind CSS configuration object, ready to drop into your tailwind.config.js.
This guide explains how Tailwind's shade system works, how to generate custom scales using ColorFYI's Shade Generator, and how to configure Tailwind to use them effectively, including dark mode.
How Tailwind's Shade System Works
Tailwind's color scale is built around an 11-step numeric system:
50 100 200 300 400 500 600 700 800 900 950
Each step represents a perceptual lightness level:
- 50 is the lightest โ nearly white, just a hint of color
- 500 is the "pure" color โ fully saturated, mid-lightness
- 950 is the darkest โ nearly black, deep tint
The numbers are not arbitrary. They are spaced to create roughly even perceptual jumps in lightness. The gap between 100 and 200 looks about the same to your eye as the gap between 700 and 800.
Why 11 steps?
11 steps provide enough granularity to cover every common use case in a UI:
| Shade | Primary Use |
|---|---|
| 50 | Page and section backgrounds, subtle tints |
| 100 | Hover backgrounds for ghost/outline elements |
| 200 | Disabled state backgrounds, subtle borders |
| 300 | Decorative borders, subtle dividers |
| 400 | Placeholder text, secondary icon color |
| 500 | The base color โ filled buttons, links |
| 600 | Hover state for filled interactive elements |
| 700 | Active/pressed state, accessible text on light backgrounds |
| 800 | Dark text on colored backgrounds, emphasis text |
| 900 | Headings, high-contrast text |
| 950 | Near-black tints, maximum contrast text |
This system means every Tailwind color works like a mini design system on its own. If you need white text readable on a filled button, use -600. If you need a barely-there background tint, use -50.
The 50โ950 Scale in Detail
Let us look at a concrete example using Tailwind's built-in violet scale:
| Shade | Hex | RGB Lightness (L in OKLCH) |
|---|---|---|
| violet-50 | #F5F3FF | ~98% |
| violet-100 | #EDE9FE | ~95% |
| violet-200 | #DDD6FE | ~89% |
| violet-300 | #C4B5FD | ~80% |
| violet-400 | #A78BFA | ~70% |
| violet-500 | #8B5CF6 | ~57% |
| violet-600 | #7C3AED | ~48% |
| violet-700 | #6D28D9 | ~40% |
| violet-800 | #5B21B6 | ~33% |
| violet-900 | #4C1D95 | ~26% |
| violet-950 | #2E1065 | ~15% |
Notice that the base color violet-500 sits at roughly 57% lightness โ not exactly the middle of 0โ100%, but positioned slightly above the midpoint to keep the scale visually balanced. Very dark shades compress into a smaller lightness range (15โ40%) because the human eye distinguishes dark shades less precisely than light ones.
Generating Custom Color Scales
Using ColorFYI's Shade Generator
The Shade Generator takes any hex code and outputs a complete Tailwind-formatted scale. Here is the workflow:
Step 1: Enter your brand color in the input field.
For example, your brand uses the exact blue #0057B8 โ a medium-dark blue used by many enterprise brands.
Step 2: The generator computes all 11 shades using a perceptually uniform algorithm, showing you the hex code and a visual preview of each step.
Step 3: Copy the generated Tailwind configuration block.
The output for #0057B8 looks approximately like this:
brand: {
50: '#E6F0FF',
100: '#CCE1FF',
200: '#99C3FF',
300: '#66A4FF',
400: '#3386FF',
500: '#0057B8', // Your input color, anchored at 500
600: '#0049A3',
700: '#003B8A',
800: '#002D6B',
900: '#001F4D',
950: '#001230',
},
What "anchoring" means
The shade generator anchors your input color at the 500 position by default. This means the input color becomes the center of the scale โ five lighter shades are generated above it, and five darker shades below.
Some generators allow you to anchor at a different position. If your brand color is already a very dark navy, anchoring it at 700 or 800 may produce a more useful range. If it is a very light pastel, anchoring at 200 or 300 makes more sense. The Shade Generator lets you adjust the anchor point.
Why perceptual uniformity matters
A naive shade generator might just decrease the HSL L value by equal increments: 95%, 85%, 75%, 65%, 55%, 45%, 35%, 25%, 15%. The math is simple, but the visual result is uneven. The transitions at the light end of the scale look spaced further apart than at the dark end, because human vision is more sensitive to lightness differences in midtones.
ColorFYI's generator uses OKLCH lightness interpolation, which produces steps that appear visually equidistant โ matching the perceptual quality of Tailwind's hand-crafted default scales.
Configuring tailwind.config.js
Extending with a custom color
The safest way to add a custom color scale is to extend Tailwind's defaults rather than replace them:
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
extend: {
colors: {
brand: {
50: '#E6F0FF',
100: '#CCE1FF',
200: '#99C3FF',
300: '#66A4FF',
400: '#3386FF',
500: '#0057B8',
600: '#0049A3',
700: '#003B8A',
800: '#002D6B',
900: '#001F4D',
950: '#001230',
},
},
},
},
}
After adding this, you can use classes like bg-brand-500, text-brand-700, border-brand-200, and hover:bg-brand-600 throughout your project.
Replacing a built-in color
If you want to completely replace a default color (e.g., replace Tailwind's blue with your brand blue):
module.exports = {
theme: {
extend: {
colors: {
blue: {
50: '#E6F0FF',
// ... through 950
},
},
},
},
}
Classes like bg-blue-500, text-blue-700 will now use your custom scale instead of Tailwind's built-in blue.
Using CSS variables for runtime theming
For applications that need runtime theme switching (e.g., white-label products, user-customizable themes), define the scale as CSS custom properties:
/* globals.css */
:root {
--color-brand-50: #E6F0FF;
--color-brand-100: #CCE1FF;
--color-brand-200: #99C3FF;
--color-brand-300: #66A4FF;
--color-brand-400: #3386FF;
--color-brand-500: #0057B8;
--color-brand-600: #0049A3;
--color-brand-700: #003B8A;
--color-brand-800: #002D6B;
--color-brand-900: #001F4D;
--color-brand-950: #001230;
}
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
brand: {
50: 'var(--color-brand-50)',
100: 'var(--color-brand-100)',
// ... through 950
},
},
},
},
}
Now changing the CSS variables at runtime (via JavaScript) instantly recolors your entire UI.
Tailwind v4 configuration
Tailwind CSS v4 moves configuration entirely into CSS using @theme:
@import "tailwindcss";
@theme {
--color-brand-50: #E6F0FF;
--color-brand-100: #CCE1FF;
--color-brand-200: #99C3FF;
--color-brand-300: #66A4FF;
--color-brand-400: #3386FF;
--color-brand-500: #0057B8;
--color-brand-600: #0049A3;
--color-brand-700: #003B8A;
--color-brand-800: #002D6B;
--color-brand-900: #001F4D;
--color-brand-950: #001230;
}
No tailwind.config.js needed. The --color-brand-* variables are automatically available as utility classes (bg-brand-500, text-brand-700, etc.).
Dark Mode Shades
Dark mode does not invert your color scale โ it reverses which shades you use. The same scale works for both light and dark mode; you just swap which end of the scale handles backgrounds and which handles text.
The inversion principle
| Role | Light Mode | Dark Mode |
|---|---|---|
| Page background | brand-50 | brand-950 |
| Surface/card background | brand-100 | brand-900 |
| Subtle border | brand-200 | brand-800 |
| Muted text | brand-400 | brand-600 |
| Body text | brand-700 | brand-300 |
| Heading text | brand-900 | brand-100 |
| Filled button | brand-500 | brand-500 |
| Button hover | brand-600 | brand-400 |
The filled button color (brand-500) stays the same in both modes โ it is the anchor point. Everything around it flips: light backgrounds become dark backgrounds, dark text becomes light text.
Implementing with Tailwind's dark mode
<!-- Background: light-50 in light, dark-950 in dark -->
<div class="bg-brand-50 dark:bg-brand-950">
<!-- Card: light-100 in light, dark-900 in dark -->
<div class="bg-brand-100 dark:bg-brand-900 rounded-lg p-6">
<!-- Heading: dark-900 text in light, light-100 in dark -->
<h2 class="text-brand-900 dark:text-brand-100">Card Title</h2>
<!-- Body text: dark-700 in light, light-300 in dark -->
<p class="text-brand-700 dark:text-brand-300">Card content goes here.</p>
<!-- Button: always brand-500, hover shifts direction per mode -->
<button class="bg-brand-500 hover:bg-brand-600 dark:hover:bg-brand-400 text-white">
Action
</button>
</div>
</div>
Generating a separate dark palette
For some design systems, especially those with significant visual separation between light and dark mode, you may want to generate a separate "dark" scale. This could be:
- A slightly warmer or cooler version of the same hue (more saturated for dark mode, since dark backgrounds need more vivid colors to look equivalent)
- A complementary hue that works better against dark backgrounds
Generate both scales with the Shade Generator and define them as separate tokens:
:root {
/* Light mode scale */
--color-brand-500: #0057B8;
}
[data-theme="dark"] {
/* Dark mode scale (slightly more saturated) */
--color-brand-500: #3386FF;
}
Common Custom Scale Scenarios
Matching a brand color exactly
Many brand guidelines specify a single Pantone or hex code. If your brand color is #E63946 (a vivid red), generate the scale anchored at 500. Your brand red becomes brand-500, and you get the full range for design flexibility.
Adding a warm neutral gray
Default gray scales in Tailwind are cool-leaning. To create a warm gray that harmonizes with an orange or red primary, generate a shade scale for a desaturated warm color like #8B7355, then use it as your neutral gray. The slight warmth creates visual coherence with your primary.
Creating semantic color scales
Your design system likely needs semantic scales:
- Success: Generate from a green like #16A34A
- Warning: Generate from an amber like #D97706
- Error/Danger: Generate from a red like #DC2626
- Info: Generate from a sky blue like #0284C7
Each becomes a named scale in your config (success, warning, error, info) alongside your brand primary and neutral scales.
Key Takeaways
- Tailwind's 50โ950 shade system provides 11 perceptually spaced lightness steps, from near-white to near-black, designed to cover every UI use case.
- ColorFYI's Shade Generator converts any single hex code into a complete Tailwind-ready scale using a perceptually uniform algorithm.
- Extend
tailwind.config.jsusingtheme.extend.colorsto add custom scales without losing Tailwind's defaults; use@themein Tailwind v4. - Use CSS custom properties (
var(--color-brand-500)) for runtime theme switching and white-label applications. - Dark mode does not need a different color โ it uses the same scale inverted: light shades become backgrounds, dark shades become text.
- Generate separate scales for your primary, neutral/gray, and semantic (success, warning, error, info) colors to build a complete design system.
- Use the numeric naming convention consistently so developers know exactly which shade to reach for:
600for hover states,700for accessible text on white,100for subtle backgrounds.