ToolPal
Gradient color swatches fanning out from dark to light tones

Color Shades Generator: Build a Complete Palette from One Color

πŸ“· Pawel Czerwinski / Pexels

Color Shades Generator: Build a Complete Palette from One Color

Learn how to generate color shades and tints for design systems, Tailwind CSS custom colors, and CSS custom properties from a single base color.

April 12, 202610 min read

Every design system eventually needs a color scale β€” a range of shades from light to dark for each brand color. You need them for backgrounds, borders, text, hover states, focus rings, and disabled states. Building one by hand, shade by shade, is genuinely tedious. And if you do it by eye, the results are usually uneven β€” some jumps are too big, others too subtle.

The Color Shades Generator takes a single base color and produces a complete, evenly stepped palette in about one second. This post explains how it works, how to use the output in your projects, and where the approach has real limitations.

What Shades and Tints Actually Are

Before getting into the tool, it helps to be clear on terminology, because "shades" gets used loosely.

Shades are darker variations of a color β€” technically, a color mixed with black. Tints are lighter variations β€” a color mixed with white. Together, shades and tints give you the full range from a near-black dark tone to a near-white pale tone.

In practice, most design systems use the combined range and just call the whole thing "the color scale" or "the color palette." What matters isn't the terminology but the result: a set of coordinated colors from light to dark that you can use consistently throughout a UI.

The typical structure looks like this:

StepUsage
50Very light background, hover states on white
100Light background, selected state backgrounds
200Borders on light backgrounds, subtle fills
300Disabled text, placeholder text
400Secondary text, muted labels
500Primary β€” usually the base color itself
600Button hover states, slightly darker primary
700Pressed states, darker interactive elements
800Dark text on light backgrounds
900Very dark, heading text alternatives
950Near-black, dark mode base

Tailwind popularized this 11-step system (50 through 950), and it has become enough of a standard that it's worth following even if you're not using Tailwind.

How the Generation Works: HSL Adjustments

The generator works in HSL color space β€” Hue, Saturation, Lightness. If you're not familiar with HSL, the quick version: Hue is the color angle (0–360, where 0 is red, 120 is green, 240 is blue), Saturation is the intensity (0% is gray, 100% is fully vivid), and Lightness goes from 0% (black) to 100% (white).

Given a base color, the tool:

  1. Converts the base to HSL
  2. Keeps the Hue fixed (it's the same color family throughout)
  3. Generates Lightness values spread across a range β€” roughly 95% for the lightest step down to 10% for the darkest
  4. Optionally makes subtle Saturation adjustments at the extremes to compensate for optical illusions

That last point is worth explaining. Human color perception is non-linear. In pure HSL, a light blue at 90% Lightness often looks nearly white and completely washed out β€” the saturation "disappears" perceptually at high lightness values. Many professional palette generators compensate by slightly boosting Saturation at the light end to keep the hue visible, and pulling back Saturation at the dark end where it tends to look muddy.

The result is a palette that looks evenly spaced to human eyes, not just evenly spaced mathematically.

Why the 50–950 Convention

Tailwind CSS deserves credit for standardizing this. Before Tailwind, everyone used different naming conventions: "light blue," "blue-lighter," "blue-dark," "blue-darkest" β€” which meant every project had its own idiosyncratic system that didn't transfer anywhere.

The numbered system (50, 100, 200 ... 900, 950) has several practical advantages:

It's easy to add steps. If you need something between 200 and 300, you add 250. There's a natural home for it.

It communicates intent at a glance. A developer looking at color-100 knows immediately it's a light background shade. color-900 is obviously dark text territory. The numbers carry semantic weight without needing descriptive names.

It's tool-compatible. Figma variables, CSS custom properties, JavaScript theme objects β€” all of them work naturally with numeric scales. And because Tailwind uses the same numbers, designers and developers are speaking the same language.

It discourages over-specificity. When colors have names like "primary-blue" and "primary-blue-slightly-lighter-for-hover," teams tend to add more and more named variants. A numbered system nudges you toward using the defined scale consistently.

Using the Output in Your Project

The generator gives you several output formats. Here's how to use each one.

CSS Custom Properties

The CSS variable output looks like this:

:root {
  --color-50: #eff6ff;
  --color-100: #dbeafe;
  --color-200: #bfdbfe;
  --color-300: #93c5fd;
  --color-400: #60a5fa;
  --color-500: #3b82f6;
  --color-600: #2563eb;
  --color-700: #1d4ed8;
  --color-800: #1e40af;
  --color-900: #1e3a8a;
  --color-950: #172554;
}

Paste this into your main CSS file inside a :root block, and the variables are available everywhere in your stylesheet:

.button-primary {
  background-color: var(--color-500);
  border-color: var(--color-600);
  color: white;
}

.button-primary:hover {
  background-color: var(--color-600);
  border-color: var(--color-700);
}

.button-primary:focus {
  outline-color: var(--color-300);
}

This approach is especially powerful for theming. If you define your brand colors as CSS custom properties, switching themes is as simple as overriding the values in a [data-theme="dark"] or .dark-mode selector.

Tailwind CSS Config

If you're using Tailwind, you can drop the palette directly into your tailwind.config.js or tailwind.config.ts file:

module.exports = {
  theme: {
    extend: {
      colors: {
        brand: {
          50: '#eff6ff',
          100: '#dbeafe',
          200: '#bfdbfe',
          // ... and so on
          950: '#172554',
        },
      },
    },
  },
}

This unlocks the full Tailwind utility class system for your brand color: bg-brand-100, text-brand-700, border-brand-300, hover:bg-brand-600, and all the rest. Your custom color behaves exactly like Tailwind's built-in palette colors.

JavaScript/TypeScript Objects

For component libraries or design tokens, a JavaScript object is often more useful than raw CSS. You can import color values directly into component code, pass them to styled-components, or use them with CSS-in-JS libraries.

Building a Design System With Color Scales

A design system typically needs at least three or four color scales:

  • Primary: your main brand color
  • Neutral/Gray: for text, backgrounds, borders β€” usually a slightly warm or cool gray rather than pure neutral
  • Semantic colors: Success (green), Warning (amber/yellow), Error (red), Info (blue)

Run each one through the shades generator separately, name them consistently, and you have the color foundation of a design system.

The typical usage pattern:

  • primary-50, primary-100 β†’ backgrounds, selected state fills
  • primary-200, primary-300 β†’ subtle borders, tags, badges
  • primary-500, primary-600 β†’ interactive elements, buttons, links
  • primary-700, primary-800 β†’ pressed states, dark interactive elements
  • neutral-100 through neutral-900 β†’ page backgrounds through body text

With this in place, every component can draw from the palette without anyone picking an arbitrary color. Consistency across a large codebase becomes a lot easier to maintain.

Comparison to the Color Palette Generator

The site also has a Color Palette Generator, and they're similar enough that it's worth clarifying the difference.

The Color Palette Generator typically generates a set of complementary or harmonious colors β€” analogous, triadic, split-complementary schemes. You give it one color and it suggests other colors that work well alongside it. It's more about color theory and finding a good color combination.

The Color Shades Generator takes one color and gives you a full range of that single color from light to dark. It's not about finding other colors β€” it's about getting all the shades of the color you already chose.

In practice, you might use both: the palette generator to find your brand color combination, and the shades generator to build the full scale for each of those colors.

Limitations Worth Knowing

I've used tools like this enough to know where they fall down. Here's what to watch out for.

Pure black and white produce useless palettes. If you enter #000000 (pure black) or #FFFFFF (pure white), the generator has no hue to work with. The entire palette will just be shades of gray. This is technically correct, but it's rarely what you want. For neutrals, use a color with at least a small amount of hue and saturation β€” something like a very slightly warm gray (#f5f0eb) will produce a much more interesting neutral scale than pure white.

Very low-saturation colors can look flat. A color that's already close to gray (say, hsl(220, 8%, 50%)) won't produce vibrant tints and shades. The light end of the scale will look nearly white and the dark end nearly black, with very little visible differentiation in between. This isn't a bug β€” it's just the nature of low-saturation colors. If your palette looks flat, try a more saturated base.

The generated palette is a starting point, not a final answer. HSL-based generation is systematic and fast, but it doesn't know anything about your specific context. Some generated light shades may not have enough contrast for text. Some darks may look slightly off in a specific context. Always verify against real UI usage and run your text/background combinations through a contrast checker.

For professional design systems, perceptual uniformity matters more. Tailwind v3's palette was hand-tuned by designers, not auto-generated. They adjusted individual steps manually to look right in context. Tools like Radix Colors use OKLCH (a perceptually uniform color space) which is more accurate than HSL for even-looking steps. The shades generator gives you a great starting point, but for a production design system at scale, you may want to hand-tune the extremes.

CSS variables named --color-500 are generic. The tool outputs variable names like --color-500. If you have multiple color scales in your project, you'll want to rename them: --brand-500, --error-500, --neutral-200, etc. Don't just dump multiple palettes into :root without namespacing them, or they'll overwrite each other.

The shades generator fits into a broader color workflow:

  • Color Picker: Pick your base color visually and get its hex or HSL value, then paste it into the shades generator.
  • Color Palette Generator: Find a harmonious color combination first, then generate shades for each color individually.
  • Color Converter: If you need to convert the generated HEX values to HSL or RGB for use in specific contexts.
  • CSS Gradient Generator: Once you have your shade scale, gradients between adjacent steps can look great β€” the gradient tool lets you compose and preview those directly.

A Practical Example: Adding a Custom Color to Tailwind

Here's a quick end-to-end workflow for adding a custom brand color to a Tailwind project:

  1. You've chosen your brand color: #0D6EFD (a strong blue).
  2. Open /tools/color-shades-generator and paste in #0D6EFD.
  3. The tool generates the full 50–950 scale.
  4. Copy the Tailwind config format output.
  5. Add it to your tailwind.config.ts under theme.extend.colors.brand.
  6. Now you can use bg-brand-500 for buttons, text-brand-700 for dark text, bg-brand-50 for hover backgrounds on white surfaces, and ring-brand-300 for focus rings.

Without the generator, you'd be manually picking all eleven shades and hoping they look coherent. With it, the whole thing takes maybe two minutes.

Conclusion

Building a color scale from scratch is the kind of task that looks straightforward and isn't. Getting the steps to feel visually even, keeping the hue consistent without looking dull, and making sure the extremes are actually usable β€” it takes more care than just darkening a hex value a fixed amount each step.

The Color Shades Generator handles all of that automatically and gives you CSS-ready output in multiple formats. It's a solid 80% solution that covers the majority of real projects, and it's the right starting point even when you plan to hand-tune afterward.

If you're building a design system, combining this with the Color Palette Generator to choose your colors and the Color Converter to validate formats gives you everything you need to get a professional-feeling color foundation in place quickly.

Frequently Asked Questions

Share this article

XLinkedIn

Related Posts