Colors & Theme

Using the color palette, customizing theme colors, and consistency.

On this page

Colors in Tailwind

Tailwind ships with a curated color palette designed to work as a system. Instead of picking random hex values, you choose from consistent steps (50–950). This makes UI feel cohesive across pages and components.

How the palette is structured

Most colors are available in multiple shades. Lower numbers are lighter, higher numbers are darker.

bg-blue-50   bg-blue-100  ...  bg-blue-900
text-gray-600
border-slate-200

Common color utilities

  • Text: text-*
  • Background: bg-*
  • Border: border-*
  • Ring (focus): ring-*
  • Divide (between children): divide-*

Practical example

<div class="rounded-lg border border-slate-200 bg-white p-6">
  <h2 class="text-slate-900 text-lg font-semibold">Title</h2>
  <p class="text-slate-600 mt-2">Supporting text</p>
  <button class="mt-4 px-4 py-2 rounded bg-blue-600 text-white hover:bg-blue-700">
    Action
  </button>
</div>

Theme mindset: choose tokens, not colors

In production you should think in roles: background, surface, border, text, muted text, accent, danger, success. Tailwind classes are the implementation detail.

Recommended baseline (simple and effective)

  • Background: gray-50 / slate-50
  • Surface: white
  • Border: slate-200
  • Text: slate-900
  • Muted text: slate-600
  • Primary: blue-600 (or brand color)
  • Danger: red-600
  • Success: green-600

Customizing colors in tailwind.config.js

If you have a brand system, extend the theme. Do not sprinkle random hex values across templates.

module.exports = {
  theme: {
    extend: {
      colors: {
        brand: {
          50: "#eef2ff",
          100: "#e0e7ff",
          200: "#c7d2fe",
          600: "#4f46e5",
          700: "#4338ca"
        }
      }
    }
  }
}

Using a brand color

<button class="bg-brand-600 hover:bg-brand-700 text-white px-4 py-2 rounded">
  Save
</button>

Dark mode and colors

Colors must be defined for both light and dark surfaces. A common pattern is to keep role-based choices consistent: light uses slate-900 text, dark uses slate-100 text.

<div class="bg-white text-slate-900 dark:bg-slate-900 dark:text-slate-100">
  ...
</div>

Avoid these production mistakes

  • Using too many different grays (gray vs slate vs zinc) in the same product.
  • Choosing random shades per component (inconsistent “feel”).
  • Hardcoding hex values everywhere instead of using tokens.
  • Not defining hover/focus/active states.

Accessibility basics

Make sure text has enough contrast against its background. If a color looks good but is hard to read, it is not production-ready.

Production checklist

  • Pick one neutral family (slate or gray) and stick to it.
  • Define role-based colors (surface, border, text, muted, primary, danger, success).
  • Use hover and focus states consistently.
  • Extend theme for brand colors instead of scattering hex values.