Chapter 4 of 14 · Tailwind CSS for Beginners — Complete Free Tutorial

Colors in Tailwind

Colour is usually the first thing you reach for, and Tailwind gives you a large, opinionated palette that behaves the same way everywhere. This chapter of the Tailwind CSS for Beginners series covers the default palette, the utilities that paint each kind of property, opacity modifiers, and how to register brand colours of your own in v4's CSS-first theme.

The default palette

Every colour ships as a family of related steps, from pale to deep, so a design can use several shades of the same hue and still look deliberate:

  • Names you know — slate, gray, zinc, neutral and stone are the cool-to-warm greys that carry most interfaces.
  • Saturated hues — red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink and rose.
  • Extremes — white, black and a 50 to 950 ladder for each family.

The numbers run 50 (lightest) through 950 (darkest), and the honest workhorses sit in the middle: 50–100 for tinted backgrounds, 200–300 for borders, 500–600 for brand accents, and 800–950 for headings. Under the hood v4 stores these as oklch values, which keep colours vivid across wide-gamut screens — you rarely need to care, because you still write indigo-600.

Staying inside one family is the fastest way to look designed. A card built from slate-50, slate-200, slate-600 and slate-900 already has hierarchy — surface, border, body text, heading — before you choose a single accent. Add the accent last, for the one thing you want noticed.

Which utility paints which property

UtilitySetsTypical use
text-emerald-600colorHeadings, labels, links
bg-slate-50background-colorPage and card surfaces
border-slate-200border-colorDividers and card edges
fill-blue-500 / stroke-blue-500SVG fill and strokeIcons drawn inline
ring-rose-500--tw-ring-colorFocus halos and selection rings
accent-indigo-600accent-colorCheckbox and radio highlights
placeholder-slate-400Placeholder text colourForm hints

One v4 change matters here: border with no colour now inherits currentColor instead of defaulting to a grey, so always write the colour — border-slate-200 — or your border will match the text.

Opacity modifiers

Instead of a separate set of "transparent" utilities, Tailwind lets you add a slash and a percentage to almost any colour:

<div class="bg-indigo-600 p-4 text-white">Solid indigo</div>
<div class="bg-indigo-600/75 p-4 text-white">75% indigo</div>
<div class="bg-indigo-600/25 p-4 text-indigo-900">25% indigo</div>

Expected output:

Three stacked bands of the same indigo, fading from fully opaque
through a soft wash to a pale tint, with the darkest text still
readable on the lightest band.

Modifiers work on text-, border-, ring- and gradients too, and arbitrary opacities such as /33 are allowed. In v3 you needed retired utilities like bg-indigo-600 bg-opacity-25; the slash form replaced all of them. A very common recipe is a 10% brand wash for hover states — hover:bg-indigo-500/10 — which reads as feedback without competing with solid buttons.

Adding your own colours

Brand colours belong in the theme, not sprinkled as hex codes. In v4 that is a CSS block in your entry file — no JavaScript configuration involved:

@import "tailwindcss";

@theme {
  --color-mint-50: oklch(0.97 0.02 165);
  --color-mint-500: oklch(0.72 0.11 178);
  --color-brand: #4f46e5;
}

Expected output:

New utilities appear: bg-mint-50, bg-mint-500, text-mint-500,
border-mint-500 and bg-brand all compile. Each value is also
published as a CSS variable on :root, so plain CSS and inline
styles can use var(--color-mint-500) too.

Because every token becomes a real variable, your whole design system stays inspectable in the browser's developer tools. The same pattern extends to fonts, spacing and breakpoints, which chapter 14 explores fully.

Naming colours you will not regret

  • Keep the ladder — define a whole family such as --color-brand-500 rather than a single --color-brand, so hover and active states have somewhere to go.
  • Name by role, use by value — --color-success says why it exists; the raw hex says nothing about intent.
  • Reserve hues — pick one accent for actions and one for status, then resist using five more "just for this screen".
  • Check contrast — text-slate-400 on white fails accessibility for body copy; the guidance in Colors & Opacity applies unchanged.

Common mistakes

  • Using raw hex codes inline — style="background:#4f46e5" bypasses the theme, so a palette change never reaches it.
  • Forgetting the slash opacity — bg-indigo-600/25 is not the same as bg-indigo-25, which does not exist.
  • Assuming grey borders — v4's border defaults to the text colour, so an uncoloured border can look alarmingly heavy.
  • Low-contrast pairings — text-slate-400 on white or text-white on amber-300 will fail an accessibility audit.
  • Repeating the same literal — if a hex value appears more than twice, it is a token waiting to be declared in @theme.

Practice checklist

  1. Restyle a simple card using only greys plus one accent family, from 50 to 900.
  2. Add an opacity-modified background such as bg-emerald-500/10 and confirm the text on it stays crisp.
  3. Declare a --color-brand-600 token and use bg-brand-600 in your markup.
  4. Inspect any element and find the --color-… variable behind its background.

Colour gives a page its mood; type gives it a voice — next up, Typography and Text Utilities.

Quiz: Colors in Tailwind

5 questions · 70% to pass

Frequently Asked Questions

Tailwind is a utility-first CSS framework: instead of writing custom classes like .card-title, you compose elements from small single-purpose utilities such as text-lg font-semibold text-slate-800. The styles ship as a generated stylesheet containing only the classes your project uses, so the CSS stays small and consistent.

Bootstrap ships a opinionated component layer (buttons, navbars with Bootstrap's own look) that you override with custom CSS. Tailwind ships primitive utilities and lets you design freely — two sites built with Tailwind can look completely different, while two Bootstrap sites tend to look related. You can still build components; you just compose them from utilities first.

You need the fundamentals: the box model, specificity, Flexbox, Grid, media queries and pseudo-classes. Tailwind does not replace CSS knowledge — it renames it. Understanding what padding, margin, gap and z-index mean makes every utility class obvious instead of something to memorise.

v4 is CSS-first: configuration lives in CSS with @import "tailwindcss" and @theme tokens instead of a JavaScript tailwind.config.js, the engine is rewritten in Rust for much faster builds, and modern CSS features (container queries, cascade layers) are built in. This tutorial teaches v4 and notes where v3 differed.

Long class lists are a real trade-off, and the tutorial covers two fixes: consistent ordering (layout → spacing → typography → colour) and small component classes for repeated combinations. The generated CSS contains only classes you actually use — Tailwind removes everything else at build time, so the stylesheet is typically smaller than an unused framework.

Three utilities cover most cases: mx-auto centres a fixed-width block horizontally, flex items-center justify-centre centres children inside a flex parent, and grid place-items-center does the same for grids. Chapter 8 and chapter 9 show both patterns with examples.

Yes — Tailwind is a build step that scans your template files for class names and generates CSS, so it works with any framework or none. It does not ship runtime JavaScript, and the classes look the same in JSX, Blade, PHP or static HTML files.

In v4 you define design tokens in CSS with @theme, for example --color-brand-500: #4f46e5; creates bg-brand-500, text-brand-500 and friends. For a one-off value you can always use arbitrary values like bg-[#0f172a], which need no configuration at all.

A variant prefixes a utility with the condition it applies under: hover:bg-indigo-600 on hover, focus:ring-2 while focused, dark:bg-slate-900 in dark mode, and sm: / md: / lg: at breakpoints. Variants stack, such as md:hover:text-lg, and chapter 11 covers the full pattern.

Yes. Tailwind compiles to a static stylesheet with no JavaScript requirement, and because it ships only used classes, pages stay fast — a Core Web Vitals win that helps SEO. Accessibility, semantic markup and good content remain your job; Tailwind only styles what you write.