Skip to content

Tailwind CSS Custom Colors — Brand Palettes and Extended Themes

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you will learn about Tailwind CSS Custom Colors. We cover key concepts, practical examples, and best practices to help you master this topic.

Tailwind CSS custom colors are defined in the theme.extend.colors configuration, supporting custom shade scales, CSS variable colors, and automatic opacity modifier support.

What You'll Learn

You will learn how to add custom brand colors, create shade scales, use CSS variables for dynamic theming, override default colors, and ensure Accessibility with proper contrast.

Why It Matters

Brand identity requires specific colors. DodaTech uses custom color palettes across all products from Durga Antivirus Pro (dark purple/blue) to Doda Browser (clean blue/gray).

Real-World Use

DodaZIP uses a custom orange/blue brand palette with 50-900 shades each, configured once in Tailwind and used as bg-brand-500, text-brand-700, border-brand-300 across the entire site.

flowchart LR
    A[Custom Fonts] --> B[Custom Colors]
    B --> C[Brand Palettes]
    B --> D[CSS Variables]
    B --> E[Opacity]
    B --> F[Accessibility]
    style B fill:#38bdf8,stroke:#0284c7,color:#fff
    style C fill:#22c55e,stroke:#16a34a,color:#fff

Defining a Brand Color Scale

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        brand: {
          50: '#eff6ff',
          100: '#dbeafe',
          200: '#bfdbfe',
          300: '#93c5fd',
          400: '#60a5fa',
          500: '#3b82f6',
          600: '#2563eb',
          700: '#1d4ed8',
          800: '#1e40af',
          900: '#1e3a8a',
          950: '#172554',
        },
      },
    },
  },
}
<div class="grid grid-cols-5 gap-2 p-4">
  <div class="bg-brand-50 p-3 rounded text-xs text-center">50</div>
  <div class="bg-brand-100 p-3 rounded text-xs text-center">100</div>
  <div class="bg-brand-200 p-3 rounded text-xs text-center">200</div>
  <div class="bg-brand-300 p-3 rounded text-xs text-center">300</div>
  <div class="bg-brand-400 p-3 rounded text-xs text-center">400</div>
  <div class="bg-brand-500 text-white p-3 rounded text-xs text-center">500</div>
  <div class="bg-brand-600 text-white p-3 rounded text-xs text-center">600</div>
  <div class="bg-brand-700 text-white p-3 rounded text-xs text-center">700</div>
  <div class="bg-brand-800 text-white p-3 rounded text-xs text-center">800</div>
  <div class="bg-brand-900 text-white p-3 rounded text-xs text-center">900</div>
</div>

Expected output: A full brand color scale from 50 (lightest) to 900 (darkest) with automatic text color adjustments for contrast.

Multiple Brand Colors

module.exports = {
  theme: {
    extend: {
      colors: {
        primary: {
          50: '#f0fdf4',
          100: '#dcfce7',
          500: '#22c55e',
          600: '#16a34a',
          700: '#15803d',
        },
        secondary: {
          50: '#f8fafc',
          100: '#f1f5f9',
          500: '#64748b',
          600: '#475569',
          700: '#334155',
        },
        accent: {
          50: '#fdf4ff',
          100: '#fae8ff',
          500: '#d946ef',
          600: '#c026d3',
          700: '#a21caf',
        },
      },
    },
  },
}
<div class="grid grid-cols-3 gap-4 p-4">
  <div class="bg-primary-500 text-white p-6 rounded-lg text-center font-bold">
    Primary
  </div>
  <div class="bg-secondary-500 text-white p-6 rounded-lg text-center font-bold">
    Secondary
  </div>
  <div class="bg-accent-500 text-white p-6 rounded-lg text-center font-bold">
    Accent
  </div>
</div>

Expected output: Three brand color sets (primary green, secondary gray, accent pink) used as background utilities.

CSS Variable Colors

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: {
          50: 'rgb(var(--color-primary-50) / <alpha-value>)',
          100: 'rgb(var(--color-primary-100) / <alpha-value>)',
          500: 'rgb(var(--color-primary-500) / <alpha-value>)',
          600: 'rgb(var(--color-primary-600) / <alpha-value>)',
          700: 'rgb(var(--color-primary-700) / <alpha-value>)',
        },
      },
    },
  },
}
/* In your main CSS */
:root {
  --color-primary-50: 240 253 244;
  --color-primary-100: 220 252 231;
  --color-primary-500: 34 197 94;
  --color-primary-600: 22 163 74;
  --color-primary-700: 21 128 61;
}

.dark {
  --color-primary-50: 5 46 22;
  --color-primary-500: 34 197 94;
  --color-primary-700: 187 247 208;
}
<div class="bg-primary-500/50 text-white p-4 rounded">
  Primary with 50% opacity (CSS variable based)
</div>

Expected output: Colors defined as CSS variables support opacity modifiers like /50, /75. The dark variant changes the variable values.

Overriding Default Colors

// Override specific default colors
module.exports = {
  theme: {
    extend: {
      colors: {
        // Rename the default blue palette
        blue: {
          500: '#6366f1', // Indigo instead of blue
          600: '#4f46e5',
          700: '#4338ca',
        },
        // Keep all other defaults
      },
    },
  },
}

Expected output: The blue palette is overridden with indigo-like values. All other Tailwind default colors remain unchanged.

Using the Color Generator

// Use a color palette generator for consistent scales
module.exports = {
  theme: {
    extend: {
      colors: {
        dodatech: {
          50: '#faf5ff',
          100: '#f3e8ff',
          200: '#e9d5ff',
          300: '#d8b4fe',
          400: '#c084fc',
          500: '#a855f7',
          600: '#9333ea',
          700: '#7e22ce',
          800: '#6b21a8',
          900: '#581c87',
          950: '#3b0764',
        },
      },
    },
  },
}

Expected output: A custom purple theme for DodaTech with full shade range from light lavender to deep purple.

Common Mistakes

1. Not Extending, Overriding

Putting colors directly in theme.colors replaces the entire default color palette, breaking bg-blue-500, text-gray-700, and hundreds of other utilities.

2. Only Defining a Few Shades

Defining only brand-500 means no brand-100, brand-200, etc. Most designs need the full range. Define at least 50, 100, 200, 500, 600, 700.

3. Ignoring Color Contrast

Light shades (50, 100) need dark text. Dark shades (800, 900) need white text. Verify contrast ratios for accessibility.

4. Using Hex Values Without Opacity Support

Custom colors defined as hex strings do not support the /50 opacity syntax. Use RGB CSS variables for opacity support.

5. Duplicating Default Colors

If a custom color matches a default (like your blue is similar to Tailwind's blue), consider using the default palette with overrides instead of adding new keys.

Practice Questions

  1. Where do you add custom colors in the config? In theme.extend.colors to add without removing defaults, or theme.colors to replace the entire palette.

  2. How do opacity modifiers work with custom colors? Colors defined as CSS variables with <alpha-value> support opacity: bg-primary-500/50.

  3. How many shades should a brand color have? At minimum 50, 100, 200, 500, 600, 700. Ideally 50 through 950 for full flexibility.

  4. What happens when you override theme.colors completely? All default Tailwind colors (blue, red, green, gray, etc.) are removed. Only your custom colors exist.

  5. How do you ensure accessible contrast with custom colors? Test light shades on white and dark shades on white with a WCAG contrast checker.

Challenge

Create a complete brand color system with 4 custom colors (primary, secondary, accent, neutral), each with 50-950 shade range. Use CSS variables for opacity support. Test with background, text, and border utilities.

FAQ

Can I use Tailwind color names like red-500 in custom overrides?

Yes. You can override any default color name in theme.extend.colors, and all existing red-* utilities use the new values.

How do I generate a color shade scale?

Use tools like Tailwind Shades, uicolors.app, or the Tailwind CSS color palette generator.

Can I use OKLCH or other color spaces?

Yes. Use the CSS color function: colors: { brand: 'oklch(0.5 0.2 270)' } and Tailwind processes it.

Do custom colors work with ring utilities?

Yes. ring-brand-500 works with custom colors, including opacity: ring-brand-500/30.

How do I share custom colors across projects?

Extract the colors object into a shared npm package or a config partial that you import into each project's tailwind.config.js.

Mini Project

Create a full brand theme with 4 color palettes (primary blue, secondary teal, accent coral, neutral slate). Apply them to a landing page: navbar, hero, feature cards, testimonials, and footer. Ensure accessible contrast.

What's Next

Now master Plugins for extending Tailwind with third-party and custom plugins. Learn how plugins add new utilities, components, and variants.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro