Tailwind CSS ships with a beautiful default color palette. But the moment your brand uses a specific shade of teal or a particular warm orange, those defaults don't cut it anymore. You need custom color scales — the full 50 through 950 range — that match your brand and still play nicely with Tailwind's utility class system.
Building those scales by hand is tedious. You'd need to pick 11 shades per color, make sure they're evenly distributed in perceived lightness, and test them across light and dark backgrounds. That's a lot of trial and error for a single color. Multiply that by three or four brand colors, and you've lost an afternoon.
There's a faster way.
How Tailwind's color scale works
Tailwind organizes each color into 11 steps: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, and 950. The numbering follows a pattern — lower numbers are lighter, higher numbers are darker. The 500 shade is typically the "base" or the most recognizable version of the color.
Here's what matters about this system:
- 50 is barely tinted white — great for subtle backgrounds
- 100-200 work for hover states and light fills
- 300-400 are good for borders and secondary elements
- 500 is your primary, mid-range shade
- 600-700 handle text on light backgrounds and hover states on dark buttons
- 800-950 are near-black variants for dark mode surfaces and high-contrast text
When you create a custom palette, you need all 11 steps to follow this same lightness curve. Skip one, and your utility classes will have gaps. Make the spacing uneven, and your UI will look inconsistent when you switch between shades.
Generating a palette from a single color
The easiest approach? Start with one color — your brand's primary — and generate the rest algorithmically. The Tailwind Color Generator does exactly this. Drop in a hex code, and it produces all 11 shades instantly.
Here's what happens under the hood. The tool converts your color to HSL (hue, saturation, lightness), then creates variations by adjusting the lightness value at each step while tweaking saturation slightly to keep colors vibrant. Lighter shades get desaturated a touch so they don't look neon. Darker shades stay rich without turning muddy.
The output looks something like this in your tailwind.config.js:
module.exports = {
theme: {
extend: {
colors: {
brand: {
50: '#f0f7ff',
100: '#e0effe',
200: '#bae0fd',
300: '#7ccbfc',
400: '#36b2f8',
500: '#0c99e9',
600: '#007ac7',
700: '#0061a2',
800: '#045285',
900: '#0a446e',
950: '#062b49',
},
},
},
},
}
Now you can use bg-brand-100, text-brand-700, border-brand-300 — all the usual Tailwind patterns, but with your colors.
Fine-tuning your palette
Automated generation gets you 90% of the way there. But sometimes a shade needs manual adjustment. Maybe 300 looks too similar to 400, or 900 feels too blue compared to the rest of the scale.
This is where the Color Scale Generator comes in handy. It gives you a visual representation of your entire scale and lets you tweak individual stops. You can see all 11 shades side by side, compare them against text samples, and adjust until every step feels intentional.
A few things to watch for when fine-tuning:
- The 50-to-100 jump should be subtle. If it's too dramatic, light backgrounds will feel jarring.
- Check 600 and 700 against white text. These are the shades you'll most often pair with white labels on buttons, and they need to pass contrast requirements.
- Compare 800 and 900 in dark mode. They'll serve as your dark surfaces, and too little difference between them makes your UI feel flat.
Getting contrast right
Speaking of contrast — this matters more than most people realize when building color palettes. A gorgeous color scale is useless if your text isn't readable against it.
The rule of thumb: use shades 600 and above for text on light backgrounds, and shades 300 and below for text on dark backgrounds. The 500 shade is a gray area (sometimes literally) — it might pass WCAG contrast checks against white, or it might not, depending on the hue.
Blue hues are especially tricky. A blue-500 that looks perfectly readable on your monitor might fail on a low-contrast laptop screen. Always verify with an actual contrast checker rather than trusting your eyes.
Using CSS variables instead of config values
Tailwind v4 introduced CSS-based configuration, and it changes how you might set up custom colors. Instead of editing a JavaScript config file, you can define your palette as CSS custom properties:
@theme {
--color-brand-50: #f0f7ff;
--color-brand-100: #e0effe;
--color-brand-200: #bae0fd;
--color-brand-300: #7ccbfc;
--color-brand-400: #36b2f8;
--color-brand-500: #0c99e9;
--color-brand-600: #007ac7;
--color-brand-700: #0061a2;
--color-brand-800: #045285;
--color-brand-900: #0a446e;
--color-brand-950: #062b49;
}
This approach has a nice bonus — you can swap palettes at runtime by overriding the variables. Want a "winter theme" toggle on your marketing site? Change the CSS variables and every bg-brand-* class updates automatically.
Multiple brand colors
Most projects need more than one custom color. You might have a primary brand color, a secondary accent, and a neutral gray that isn't Tailwind's default slate or zinc.
The process is the same for each: pick your base shade, generate the scale, fine-tune it, and add it to your config. But here's an extra step that's easy to miss — make sure your colors work together, not just individually.
Place your primary-500 next to your secondary-500. Do they clash? Now check primary-200 as a background with secondary-700 as text. Does it feel cohesive?
Building a multi-color palette is really about relationships between colors, not just individual scales. Generate each scale with the Tailwind Color Generator, then lay them out side by side to check harmony.
Dark mode considerations
If your project supports dark mode (and it probably should), your custom palette needs to hold up in both contexts.
Here's a pattern that works well:
- Light mode backgrounds: 50, 100
- Light mode text on colored surfaces: 700, 800
- Dark mode backgrounds: 900, 950
- Dark mode text on colored surfaces: 200, 300
The key insight is that your palette essentially gets used in reverse. Light mode leans on the low end of the scale for fills and the high end for text. Dark mode flips that. A well-constructed scale handles this naturally — another reason to use a generator rather than hand-picking shades.
Common mistakes to avoid
Starting with a shade that's too dark or too light. Your base color should be close to the 500 position — a solidly mid-range shade. If you start with something very light (like a pastel), the generator can't create meaningful lighter stops above it.
Ignoring the neutral scale. Even if you keep Tailwind's default grays, consider generating a custom neutral that has a slight warm or cool tint matching your brand. A warm brand palette paired with cool slate grays feels disconnected.
Copying palettes from other sites without testing. Someone else's carefully crafted palette was built for their design system, their fonts, their spacing. Borrow ideas, but always test colors in your own context.
Putting it all together
Here's a quick workflow that saves time:
- Pick your primary brand color (the one in your logo or brand guidelines)
- Drop it into the Tailwind Color Generator to create the full 50-950 scale
- Use the Color Scale Generator to visualize and fine-tune any awkward stops
- Repeat for secondary and accent colors
- Add everything to your Tailwind config or CSS theme block
- Test across light mode, dark mode, and different screen brightnesses
That's really it. Custom Tailwind palettes don't have to eat up your day. Generate the scales, verify the contrast, and ship it.