Market
Pricing
Sign inStart
Field GuideCSS and web
CSS and web

Tailwind colours: using and extending the palette

The default palette is a good starting point and a poor finishing one, because thousands of sites share it. Here is how Tailwind colours work in v4, and how to add your own without breaking anything.

GradientlyVerified Gradiently account·October 1, 2026·5 min read
Cover: Frost of Tin · GR·0Z1J·NS

The short version

  • Tailwind colors are named families such as blue, violet and slate, each with shades from 50 for the lightest to 950 for the darkest.
  • In Tailwind v4 every colour is a CSS variable such as --color-blue-500, defined in OKLCH, and you add or replace colours inside an @theme block in your CSS.
  • Any variable you name --color-something in @theme becomes a full set of utilities, including bg-something, text-something and border-something.
  • The opacity modifier, as in bg-sky-500/50, works with custom colours too, because v4 mixes the transparency in with color-mix().
  • Contrast depends on the pair, not the shade number, so check text and background combinations rather than assuming 500 on white is readable.
On this page
How the default palette is organisedUsing Tailwind colours in your markupAdding custom colours in Tailwind v4Custom colours in Tailwind v3Contrast: which shades are safe for textMake the palette yours

Tailwind colors are a set of named families, from red to rose plus a set of greys such as slate, gray, zinc, neutral and stone, each with eleven shades numbered 50, 100 to 900 in hundreds, and 950. You apply them with utilities such as bg-blue-600, text-slate-900 and border-rose-300. In Tailwind v4 the whole palette is defined in OKLCH as CSS variables, which you extend or replace in an @theme block rather than a JavaScript config file.

How the default palette is organised

Every family follows the same ladder. 50 to 200 are tints for backgrounds and hover fills, 300 and 400 are soft accents, 500 and 600 are the saturated middle, and 700 to 950 are for text, borders and dark surfaces. Because each family uses the same steps, swapping blue for violet in a component usually just works.

The blue family as sRGB hex, from the v3 palette. The v4 values are written in OKLCH and are slightly more vivid on wide gamut screens, but the ladder is the same.
Greysslate, gray, zinc, neutral, stone

Typical use

Text, borders, surfaces
Warmred, orange, amber, yellow

Typical use

Alerts, warnings, energy
Greenslime, green, emerald, teal

Typical use

Success, nature, calm
Bluescyan, sky, blue, indigo

Typical use

Links, primary actions
Purples and pinks

Families

violet, purple, fuchsia, pink, rose

Typical use

Accents, creative brands
GroupFamiliesTypical use
Greysslate, gray, zinc, neutral, stoneText, borders, surfaces
Warmred, orange, amber, yellowAlerts, warnings, energy
Greenslime, green, emerald, tealSuccess, nature, calm
Bluescyan, sky, blue, indigoLinks, primary actions
Purples and pinksviolet, purple, fuchsia, pink, roseAccents, creative brands
The default families grouped by temperature. Slate and zinc lean cool, stone leans warm, neutral has no tint at all.

Pick one grey and stick to it. Mixing gray-500 text with slate-200 borders gives a faintly dirty look that is hard to name and easy to avoid.

Using Tailwind colours in your markup

Colour utilities exist for almost every property that takes a colour: bg-*, text-*, border-*, ring-*, fill-*, stroke-*, decoration-*, shadow-*, accent-*, caret-* and the gradient stops from-*, via-* and to-*. Add a slash and a number to set opacity.

html
<div class="rounded-xl bg-slate-900 p-6 text-slate-100">
  <p class="text-sm text-slate-400">Status</p>
  <p class="text-2xl font-semibold">All systems normal</p>
  <span class="mt-4 inline-flex rounded-full bg-emerald-500/15 px-3 py-1 text-emerald-300">
    Live
  </span>
</div>

<!-- One off values when nothing in the palette fits -->
<button class="bg-[#0b5c4a] text-[oklch(97%_0.02_160)]">Book a table</button>
A dark card from one grey family plus one accent at 15% opacity. Arbitrary values in square brackets cover the rare exception.

In v4 every shade is also a variable you can use in plain CSS: color: var(--color-slate-400). That makes it easy to style third party widgets, SVG or a canvas with the same colours as your utilities.

Adding custom colours in Tailwind v4

In v4 you configure the theme in CSS. Any variable that starts with --color- inside @theme becomes a colour, with every utility generated for it. Name colours by role or by brand, and give them a full ladder if you will need tints.

css
@import "tailwindcss";

@theme {
  /* A brand ramp on one hue, written in OKLCH */
  --color-ember-50: oklch(97% 0.02 45);
  --color-ember-100: oklch(94% 0.04 45);
  --color-ember-200: oklch(88% 0.07 45);
  --color-ember-300: oklch(80% 0.11 45);
  --color-ember-400: oklch(71% 0.15 45);
  --color-ember-500: oklch(63% 0.17 45);
  --color-ember-600: oklch(55% 0.16 45);
  --color-ember-700: oklch(47% 0.14 45);
  --color-ember-800: oklch(39% 0.11 45);
  --color-ember-900: oklch(31% 0.08 45);
  --color-ember-950: oklch(22% 0.05 45);

  /* Single role colours */
  --color-ink: oklch(18% 0.02 270);
  --color-paper: oklch(98% 0.01 85);
}
Now bg-ember-500, text-ink, border-ember-200/60 and from-ember-400 all exist.
The ember ramp above, converted to hex. Holding the hue at 45 and stepping lightness keeps every shade recognisably the same colour.

Building the ramp in OKLCH is the reason this works. Lightness in OKLCH matches how bright a colour looks, so equal steps look equal, which HSL cannot promise. OKLCH explained goes deeper, and oklch.com is a good place to try values.

Replacing the palette entirely

To remove the defaults and keep only your own colours, reset the namespace first with --color-*: initial; at the top of @theme. Utilities like bg-blue-500 will then stop existing, which is a useful guard on a project with a strict brand.

Custom colours in Tailwind v3

Older projects still configure colours in JavaScript. Use extend to add colours beside the defaults, or set colors directly to replace them.

js
// tailwind.config.js (v3)
module.exports = {
  theme: {
    extend: {
      colors: {
        ember: {
          50: '#fff1ea',
          500: '#d95f19',
          900: '#502007',
        },
        ink: '#14121f',
      },
    },
  },
}
The v3 way. When you upgrade, these move into @theme as --color-ember-500 and so on.

Contrast: which shades are safe for text

Shade numbers are not a contrast scale. White text on blue-600 passes the 4.5:1 that WCAG asks for body text, while white on blue-500 does not. Check the actual pair, using the ratios below or a tool from WebAIM, and read colour contrast and accessibility for the rules.

slate-900 on white

Contrast

17.85:1

Body text

Passes
gray-500 on white

Contrast

4.83:1

Body text

Passes, just
gray-400 on white

Contrast

2.54:1

Body text

Fails
white on blue-600

Contrast

5.17:1

Body text

Passes
white on blue-500

Contrast

3.68:1

Body text

Large text only
slate-400 on slate-900

Contrast

6.96:1

Body text

Passes
Text on backgroundContrastBody text
slate-900 on white17.85:1Passes
gray-500 on white4.83:1Passes, just
gray-400 on white2.54:1Fails
white on blue-6005.17:1Passes
white on blue-5003.68:1Large text only
slate-400 on slate-9006.96:1Passes
Ratios calculated from the v3 hex values. Rerun them for your exact v4 colours, which differ slightly.

Make the palette yours

The default palette is used on a vast number of sites, which is why so many products share the same indigo-600 button and slate-50 background. That sameness is the web version of why every feed looks the same.

Looks like every other site

  • Default indigo or blue as the brand colour
  • Several grey families mixed together
  • Accent colour used on everything
  • Light theme colours reused in dark mode

Looks like you

  • One custom ramp on your own hue
  • One grey, tinted towards the brand hue
  • Accent kept for actions and one highlight
  • A dark set chosen separately, see dark mode gradients
  1. 1

    Choose a hue

    Start from your brand colour and read its hue in OKLCH. Website colour schemes helps if you have none yet.

  2. 2

    Build the ramp

    Hold the hue, step lightness from about 97% to 22%, and lower chroma at both ends.

  3. 3

    Name roles too

    Add --color-ink, --color-paper and similar, so components say what a colour is for.

  4. 4

    Keep one source

    Treat the @theme block as your design tokens, and reuse the same values in your graphics.

The last step is where brands usually drift: the site gets the new ramp while social posts and slides keep last year's colours. A Gradiently brand kit stores your palettes alongside your fonts and logos, so the Designer lays out posts in the same colours your Tailwind theme uses, and a Mark gives the brand a gradient look no other site shares.

Find a gradient that’s only yours

Browse thousands of Marks, design with any of them for free, and claim the one that feels like you.

Browse the Market

Questions people ask

What colors are in Tailwind by default?

Families from red, orange, amber and yellow through greens, blues, purples and pinks to rose, plus greys including slate, gray, zinc, neutral and stone. Each has shades 50, 100 to 900 and 950, plus black and white.

How do I add custom colors in Tailwind v4?

Define variables such as --color-brand-500 inside an @theme block in your CSS. Tailwind generates bg-brand-500, text-brand-500 and every other colour utility from it.

Does Tailwind use OKLCH?

Yes. Since v4 the default palette is defined in OKLCH, and you can write your own colours in OKLCH, hex, RGB or any other CSS colour format.

How do I use a Tailwind color in plain CSS?

In v4 use the variable directly, for example var(--color-slate-400). In v3 use the theme() function, such as theme(colors.slate.400).

Which Tailwind shades are accessible for text?

It depends on the pair. On white, gray-500 and darker pass for body text, and white text passes on blue-600 but not on blue-500, so always check the specific combination.

Share this guide

Written by GradientlyVerified Gradiently account

The team behind Gradiently, a design tool built around Marks: living gradients that make everything you design look like yours.

See our profile

On this page

How the default palette is organisedUsing Tailwind colours in your markupAdding custom colours in Tailwind v4Custom colours in Tailwind v3Contrast: which shades are safe for textMake the palette yours

Share this guide

Next in CSS and web

HTML canvas gradient: createLinearGradient, radial and conic

Keep reading

All CSS and web guides
Colour

OKLCH explained: perceptual colour for designers

5 min read

HSL promised readable colour and nearly delivered. OKLCH keeps the readable part and fixes the lie about lightness, which is why design systems are moving to it.

CSS and web

Tailwind gradient classes: linear, radial and conic in v4

5 min read

Tailwind v4 renamed its gradient utilities, added angles, radial and conic gradients, and switched the default blend to oklab. Here is the whole system, with the CSS each class produces.

CSS and web

Design tokens: one source of truth for colour and type

5 min read

A brand colour that lives in forty files will drift. A token lives in one place and every platform reads from it. Here is how to structure design tokens, name them so they last, and ship them to code and design tools.

Find the look that’s only yours.

Every Mark is a living background with one owner. Try an unclaimed Mark, and claim yours when it feels right.

Start designing

Check a certificate

Type a certificate number or a Mark’s code to see who owns it.

Works with ChatGPT and Claude

Ask your AI for a design. It makes it in your Mark, ready to edit.

ChatGPTClaude
How to connect

Product

  • Market
  • Explore
  • Pricing
  • Certificates

Learn

  • Field Guide
  • Help centre
  • What’s new

Developers

  • Overview
  • ChatGPT and Claude
  • API reference
  • API keys

Company

  • About
  • Contact us
  • Sign in

Legal

  • Terms
  • Privacy
  • Refunds
  • Mark protection
  • Cookies
  • All policies
Move through the letters. Each one wears a real Mark.Touch a letter to see its Mark.One name. Ten Marks inside it.
© 2026 Gradiently