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@themeblock in your CSS. - Any variable you name
--color-somethingin@themebecomes a full set of utilities, includingbg-something,text-somethingandborder-something. - The opacity modifier, as in
bg-sky-500/50, works with custom colours too, because v4 mixes the transparency in withcolor-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
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.
Typical use
Typical use
Typical use
Typical use
Families
Typical use
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.
<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>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.
@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);
}bg-ember-500, text-ink, border-ember-200/60 and from-ember-400 all exist.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.
// tailwind.config.js (v3)
module.exports = {
theme: {
extend: {
colors: {
ember: {
50: '#fff1ea',
500: '#d95f19',
900: '#502007',
},
ink: '#14121f',
},
},
},
}@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.
Contrast
Body text
Contrast
Body text
Contrast
Body text
Contrast
Body text
Contrast
Body text
Contrast
Body text
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
Choose a hue
Start from your brand colour and read its hue in OKLCH. Website colour schemes helps if you have none yet.
- 2
Build the ramp
Hold the hue, step lightness from about 97% to 22%, and lower chroma at both ends.
- 3
Name roles too
Add
--color-ink,--color-paperand similar, so components say what a colour is for. - 4
Keep one source
Treat the
@themeblock 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.
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.
Written by Gradiently
The team behind Gradiently, a design tool built around Marks: living gradients that make everything you design look like yours.
See our profile