اتجاهات التصميم

نظام ألوان Tailwind CSS: كيف تُولَّد الدرجات

قراءة 8 دقيقة

Tailwind CSS ships with one of the most widely used color systems in web development. Its palette of 22 color families — each divided into 11 shades from 50 to 950 — powers millions of websites and has become a de facto standard for how developers think about color scales. But where do these shades come from, how are they generated, and how can you build your own scales that fit seamlessly into the system? This article answers all of those questions.

Tailwind's Design Philosophy for Color

Tailwind does not use a simple arithmetic approach to shade generation. Instead, the Tailwind team hand-curated every shade in the original palette using a combination of perceptual lightness and aesthetic judgment, with the goal of making shades that are:

  1. Useful at every step: Each shade from 50 to 950 should be a shade that someone would plausibly want to use — not a gap-filler that ends up unused.
  2. Consistent across hues: A 500 shade of blue should feel equally "medium" in perceived brightness as a 500 shade of green, even though the underlying hex values are completely different.
  3. WCAG-aware: The darker shades (700–950) should achieve AA contrast against white; the lighter shades (50–200) should achieve AA contrast against black.

This philosophy explains why you cannot generate the Tailwind palette with a simple HSL lightness formula. Hues differ in their inherent perceptual brightness — yellow is intrinsically lighter than blue at the same HSL lightness value — so each color family requires individual tuning.

The 22 Color Families

Tailwind v3 and v4 ship with 22 named color families:

Family Representative 500 Value
Slate #64748B
Gray #6B7280
Zinc #71717A
Neutral #737373
Stone #78716C
Red #EF4444
Orange #F97316
Amber #F59E0B
Yellow #EAB308
Lime #84CC16
Green #22C55E
Emerald #10B981
Teal #14B8A6
Cyan #06B6D4
Sky #0EA5E9
Blue #3B82F6
Indigo #6366F1
Violet #8B5CF6
Purple #A855F7
Fuchsia #D946EF
Pink #EC4899
Rose #F43F5E

Notice the five neutral families (slate through stone): these are not just different saturation levels of the same gray. Each has a distinct hue cast — slate leans blue-gray, stone leans warm brown-gray, neutral is the most pure achromatic. This gives designers choices for environments that call for cool, warm, or neutral tones in their gray scaffolding.

The 11 Shade Steps

Each color family contains eleven shades:

Step Intended Use
50 Very light tints; page backgrounds, subtle dividers
100 Light tints; card backgrounds, table stripes
200 Light mid-tones; borders, disabled states
300 Mid-light; placeholder text on dark backgrounds
400 Mid-tone; secondary icons, secondary text
500 "Pure" hue; primary brand color, badges
600 Dark mid-tone; hover states for 500-colored elements
700 Dark; primary text on light backgrounds
800 Very dark; headings, high-emphasis text
900 Near-black; maximum text contrast
950 Darkest; added in Tailwind v3.3 for more shadow depth

The 950 shade was added later because designers found that 900 was sometimes not dark enough for deep shadow effects, especially in dark mode where the surface colors are very dark and need an even deeper shade for layering.

The 500 step is intentionally the "canonical" shade of each color — the one that looks most like what you would expect if someone said "I want blue" or "I want green." All other steps are understood relative to this anchor.

How the Shade Algorithm Works

While Tailwind's colors were hand-curated, the team used a process grounded in the OKLCH color space to maintain perceptual consistency. OKLCH (Oklab Lightness Chroma Hue) is designed so that equal numerical changes in lightness produce equal perceived brightness changes, unlike HSL or RGB where hue shifts dramatically alter the perceived lightness.

The general process for a color family looks like this:

  1. Choose the 500 value: Define the primary brand color for this family in OKLCH or an equivalent perceptual space.
  2. Set lightness targets for each step: Map the 11 steps to specific OKLCH lightness values — for example, step 50 might target an OKLCH lightness of 0.97, while step 950 targets 0.13.
  3. Maintain chroma and hue: Where possible, keep the chroma (saturation) and hue angle constant across steps, adjusting only lightness.
  4. Hand-adjust for hue shift: Many hues exhibit unwanted hue shifts as they get lighter or darker in OKLCH. Yellow, for example, tends to shift toward green when darkened. Human adjustment is required at each step to correct these shifts.
  5. Convert to sRGB hex: The final OKLCH values are converted to hex codes for use in CSS.

You can see the result of this process by comparing how the Tailwind palette handles yellow versus blue. Blue's steps shift slightly in temperature (the darkest blues have more indigo character), while yellow's steps shift toward olive when darkened to avoid becoming muddy. These are deliberate perceptual corrections that no pure algorithm would produce automatically.

Use the Color Converter to examine any Tailwind hex value in OKLCH space and observe how lightness, chroma, and hue change across the scale.

Customizing the Tailwind Color Palette

Tailwind v3 (tailwind.config.js)

In Tailwind v3, you extend or replace the palette in tailwind.config.js:

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        brand: {
          50:  '#f0f9ff',
          100: '#e0f2fe',
          200: '#bae6fd',
          300: '#7dd3fc',
          400: '#38bdf8',
          500: '#0ea5e9',
          600: '#0284c7',
          700: '#0369a1',
          800: '#075985',
          900: '#0c4a6e',
          950: '#082f49',
        },
      },
    },
  },
}

Using extend preserves all the built-in colors; replacing theme.colors directly removes them.

Tailwind v4 (CSS-First Configuration)

Tailwind v4 eliminates the JavaScript configuration file. Colors are now defined as CSS custom properties in your main CSS file:

@import "tailwindcss";

@theme {
  --color-brand-50: #f0f9ff;
  --color-brand-100: #e0f2fe;
  --color-brand-200: #bae6fd;
  --color-brand-300: #7dd3fc;
  --color-brand-400: #38bdf8;
  --color-brand-500: #0ea5e9;
  --color-brand-600: #0284c7;
  --color-brand-700: #0369a1;
  --color-brand-800: #075985;
  --color-brand-900: #0c4a6e;
  --color-brand-950: #082f49;
}

This generates the utility classes bg-brand-50 through bg-brand-950, text-brand-*, border-brand-*, and so on — exactly as the built-in colors work, but with your custom hue.

What Changed in Tailwind v4

Tailwind v4 introduced several significant changes to the color system:

CSS Variables as the Source of Truth

In v4, every built-in color is exposed as a CSS custom property. This means you can access any Tailwind color in plain CSS without Tailwind utility classes:

.custom-element {
  background-color: var(--color-blue-500);
  border-color: var(--color-blue-200);
}

This was not easily possible in v3 without additional tooling or manually duplicating hex values.

OKLCH Color Values

Tailwind v4 expresses its colors in OKLCH rather than sRGB hex. This has several advantages:

  • Wide gamut support: On displays that support P3 or Rec. 2020 gamuts, colors can be more vivid than what hex codes can express.
  • Better interpolation: Gradients between two Tailwind colors produce more perceptually uniform results.
  • Predictable manipulation: Adjusting lightness in OKLCH is more reliable than adjusting it in HSL.

The change is mostly transparent to developers who use utility classes — bg-blue-500 looks the same — but it matters if you are building custom gradients or animations that interpolate between colors.

Semantic Color Tokens

v4 also introduced better support for semantic color tokens — variables that describe what a color does rather than what it looks like:

@theme {
  --color-primary: var(--color-blue-600);
  --color-primary-hover: var(--color-blue-700);
  --color-surface: var(--color-slate-50);
  --color-on-surface: var(--color-slate-900);
}

This pattern maps your design system's semantic layer onto Tailwind's scale layer, giving you the ability to switch themes without changing component markup.

Building a Custom Scale That Fits Tailwind

If you need a custom color that is not in the default palette — your brand's specific orange or a bespoke green — you have two options: find the closest built-in family and adjust, or generate an entirely new scale.

Using the Shade Generator

The Shade Generator produces a complete 50–950 scale from a single input hex code. Enter your brand's primary color and the tool:

  1. Converts the hex to OKLCH
  2. Calculates lightness targets for each of the 11 steps
  3. Adjusts chroma appropriately so lighter shades are less saturated and darker shades maintain depth
  4. Outputs sRGB hex values ready to paste into your Tailwind config

For example, if your brand color is #0F766E (a teal-green), the generator might produce:

Step Hex
50 #F0FDFA
100 #CCFBF1
200 #99F6E4
300 #5EEAD4
400 #2DD4BF
500 #14B8A6
600 #0D9488
700 #0F766E
800 #115E59
900 #134E4A
950 #042F2E

This matches Tailwind's built-in Teal scale, demonstrating that the generator's output aligns with the official palette's visual character.

Using Tailwind Colors for Dark Mode

Tailwind's shade system is well-suited to dark mode because the scale provides mirror-image values. A typical convention:

Light Mode Dark Mode Purpose
slate-50 slate-900 Page background
slate-100 slate-800 Card background
slate-200 slate-700 Border
slate-900 slate-100 Body text
blue-600 blue-400 Primary action

The key insight is that you invert the shade number rather than the color. Where you use slate-100 in light mode, you use slate-900 in dark mode. For interactive colors like links and buttons, you shift from a darker shade (600) in light mode to a lighter shade (400) in dark mode, maintaining contrast against the different background.

Tailwind's dark: variant makes this systematic:

<div class="bg-slate-50 dark:bg-slate-900 text-slate-900 dark:text-slate-100">
  <button class="bg-blue-600 dark:bg-blue-400 text-white dark:text-slate-900">
    Action
  </button>
</div>

Common Color System Mistakes

Using the Same Shade for Both Modes

Applying bg-blue-600 without a dark: override is a common mistake. In dark mode, dark backgrounds with a bright blue element look fine, but a white card on a dark background becomes jarring. Always define both light and dark variants for background colors.

Picking Non-Adjacent Shades for Contrast

Using gray-400 text on a gray-300 background creates insufficient contrast. A general rule: maintain at least a 4-step gap between foreground and background shades (e.g., text on slate-100 should be at least slate-700). Use the Contrast Checker to verify specific combinations meet WCAG AA (4.5:1) or AAA (7:1).

Using Too Many Color Families

The Tailwind palette has 22 families, but most interfaces need three at most: one for neutrals (gray/slate), one for the primary brand color, and one for semantic states (red for errors, green for success, yellow for warnings). Picking four or more distinct colored families creates visual complexity without purpose.

Key Takeaways

  • Tailwind CSS ships with 22 color families, each containing 11 shades from 50 to 950, produced through perceptual lightness analysis and human curation rather than a simple arithmetic formula.
  • The five neutral families (slate, gray, zinc, neutral, stone) each have distinct hue casts, giving designers warm, cool, or neutral gray options.
  • The 500 step is the canonical "pure" shade for each color family; all other steps are understood relative to it, and the 950 step was added in v3.3 for deeper shadow and dark-surface layering.
  • Tailwind v4 moves to CSS-first configuration with @theme, exposes all colors as CSS custom properties, and uses OKLCH internally for better perceptual uniformity and wide-gamut support.
  • The Shade Generator produces a complete Tailwind-compatible 50–950 scale from any input hex code, using OKLCH-based lightness targets.
  • For dark mode, invert the shade number (50 ↔ 900) rather than inverting the hue, and shift interactive colors from darker shades (600) to lighter shades (400) to maintain contrast against dark backgrounds.

الألوان ذات الصلة

العلامات التجارية ذات الصلة

الأدوات ذات الصلة