Tints & Shades Scale Generator
Turn one brand color into an even 50–950 shade ramp interpolated in OKLCH — entirely on this device.
oklch(0.623 0.188 259.8)| Step | Swatch | Token | Hex | vs white | vs black | Notes |
|---|---|---|---|---|---|---|
| 50 | brand-50 | 1.09 | 19.18 | mapped | ||
| 100 | brand-100 | 1.22 | 17.19 | mapped | ||
| 200 | brand-200 | 1.43 | 14.69 | mapped | ||
| 300 | brand-300 | 1.86 | 11.31 | mapped | ||
| 400 | brand-400 | 2.73 | 7.69 | mapped | ||
| 500 | brand-500 | 3.68 | 5.71 | anchor | ||
| 600 | brand-600 | 5.07 | 4.14 | |||
| 700 | brand-700 | 7.03 | 2.99 | |||
| 800 | brand-800 | 9.62 | 2.18 | |||
| 900 | brand-900 | 12.75 | 1.65 | |||
| 950 | brand-950 | 15.81 | 1.33 |
Every swatch is the gamut-mapped sRGB hex — the same value the export carries. Steps marked mapped were moved into sRGB.
- 5 steps were mapped into sRGB because their exact colors are outside the sRGB gamut.
- Anchor set to step 500 — its default lightness target is the closest to your color.
/* Tailwind CSS v3 — merge into tailwind.config.js */
module.exports = {
theme: {
extend: {
colors: {
"brand": {
"50": "#e8f7ff",
"100": "#d6ebff",
"200": "#bbdbff",
"300": "#93c1ff",
"400": "#599dff",
"500": "#3b82f6",
"600": "#256ad9",
"700": "#1354b8",
"800": "#084096",
"900": "#052f70",
"950": "#07214b",
},
},
},
},
};
Not affiliated with Tailwind Labs. This page follows the 50–950 step-naming convention only; what you copy is plain CSS, SCSS, JavaScript or JSON that you own.
Press ? for shortcuts
Do it offline:$ npm i culori && node -e "const c=require('culori'),o=c.converter('oklch')(c.parse('#3b82f6')),L=[0.971,0.936,0.885,0.808,0.704,0.623,0.546,0.469,0.397,0.324,0.257];L.forEach((l,i)=>{const t=Math.abs(i-5)/5;console.log(c.formatHex(c.toGamut('rgb','oklch')({mode:'oklch',l:i==5?o.l:l,c:o.c*(1-0.55*t*t),h:o.h})))})"
How to use it
- The page opens on #3b82f6 with all eleven rows drawn.
- Paste a color in any CSS notation — hex, rgb(), hsl(), oklch() or a keyword.
- Leave the anchor on auto, or pin it to the step your shade ships as.
- Adjust the ends, the curve and the falloff until the ramp reads evenly.
- Name the family, pick a format, copy it out.
One color goes in and eleven tokens come out, numbered 50 to 950 the way utility frameworks expect. Steps are interpolated in OKLCH, so each drop in lightness looks like the one before it rather than merely measuring the same. Your color stays exact on one step, and any step sRGB cannot show is labelled.
How it works
HSL's lightness is a coordinate, not a measurement: hsl(60 100% 50%) measures 1.07 to 1 against white, hsl(240 100% 50%) 8.59 to 1. OKLCH's L is fitted to reported perception, so the house targets — 0.971 at step 50 down to 0.257 at step 950 — space evenly.
The anchor keeps your lightness, chroma and hue untouched. The other ten interpolate along two arms meeting at it, which keeps the ramp ordered wherever the anchor sits.
Chroma falls off with the square of the distance from the anchor: at the default 0.55 the far end keeps 45 percent of it. Without that, tints read as neon and shades as mud.
Steps landing outside sRGB are moved into it, then labelled and counted. The figures beside each swatch are WCAG 2 contrast ratios against white and black, at two decimal places.
Examples
#3b82f6step hex white black
50 #e8f7ff 1.09 19.18 mapped
100 #d6ebff 1.22 17.19 mapped
200 #bbdbff 1.43 14.69 mapped
300 #93c1ff 1.86 11.31 mapped
400 #599dff 2.73 7.69 mapped
500 #3b82f6 3.68 5.71 anchor
600 #256ad9 5.07 4.14
700 #1354b8 7.03 2.99
800 #084096 9.62 2.18
900 #052f70 12.75 1.65
950 #07214b 15.81 1.33
note Anchor set to step 500 — its default lightness target is the closest to your color.
note 5 steps were mapped into sRGB because their exact colors are outside the sRGB gamut.
:root {
--brand-50: #e8f7ff;
--brand-100: #d6ebff;
--brand-200: #bbdbff;
--brand-300: #93c1ff;
--brand-400: #599dff;
--brand-500: #3b82f6;
--brand-600: #256ad9;
--brand-700: #1354b8;
--brand-800: #084096;
--brand-900: #052f70;
--brand-950: #07214b;
}Step 500 is the pasted color byte for byte. The five light steps are labelled because a tint holding this much chroma leaves sRGB; contrast climbs 1.09 to 15.81 without dipping.
oklch(0.7 0.35 150)step hex white black
50 #cdffd7 1.11 18.88 mapped
100 #9affb3 1.21 17.33 mapped
200 #00ff70 1.35 15.54 mapped
300 #00e95b 1.64 12.81 mapped
400 #00c248 2.38 8.81 anchor mapped
500 #00a539 3.26 6.44 mapped
600 #008a2c 4.50 4.67 mapped
700 #007120 6.21 3.38 mapped
800 #005914 8.61 2.44 mapped
900 #004309 11.62 1.81 mapped
950 #002f02 14.92 1.41 mapped
note Anchor set to step 400 — its default lightness target is the closest to your color.
note 11 steps were mapped into sRGB because their exact colors are outside the sRGB gamut.
note Your color is outside sRGB, so step 400 shows the mapped color, not the one you typed.Chroma 0.35 in the greens exceeds sRGB at every lightness, so all eleven rows moved — the anchor included. #00c248 is the nearest sRGB green.
#808080step hex white black
50 #f5f5f5 1.09 19.26
100 #e9e9e9 1.21 17.30
200 #d7d7d7 1.44 14.59
300 #bdbdbd 1.88 11.18
400 #9a9a9a 2.81 7.46
500 #808080 3.95 5.32 anchor
600 #6b6b6b 5.33 3.94
700 #575757 7.23 2.91
800 #444444 9.74 2.16
900 #333333 12.63 1.66
950 #232323 15.72 1.34
note Anchor set to step 500 — its default lightness target is the closest to your color.
note Your color has no chroma, so it has no hue to ramp — every step stays neutral and hue is reported as 0.A neutral ramp needs no falloff and no mapping: every hex has three equal channels.
#e11d48step hex white black
50 #ffecf2 1.13 18.53 mapped
100 #ffd9e1 1.29 16.26 mapped
200 #ffbec8 1.56 13.45 mapped
300 #ff90a0 2.15 9.75 mapped
400 #ff4869 3.29 6.38 mapped
500 #e11d48 4.70 4.47 anchor
600 #c7002d 6.06 3.47 mapped
700 #a70018 7.91 2.66 mapped
800 #890006 10.16 2.07 mapped
900 #6b0000 12.92 1.63 mapped
950 #500000 15.66 1.34 mapped
note Anchor set to step 500 — its default lightness target is the closest to your color.
note Hue rotates -12° by step 50 and +12° by step 950, measured from step 500.
note 10 steps were mapped into sRGB because their exact colors are outside the sRGB gamut.Twelve degrees sends tints toward pink and shades toward brick, and the family renames to rose-50 through rose-950.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
The lightness targets are ours, not an official palette
The numbering is a convention this tool follows; the eleven lightness targets behind it were chosen here. This tool is not affiliated with or endorsed by Tailwind Labs, and its output is plain CSS, SCSS, JavaScript or JSON.
Pure white and pure black push the range open
#ffffff has lightness 1, above the default lightest end of 0.971, so the range widens to 0.257 through 1, anchoring at step 50. #000000 mirrors that at 950.
Alpha is dropped; transparent becomes a neutral
A token ramp is opaque, so #3b82f680 builds the same steps as #3b82f6, noting that alpha 0.502 was discarded. transparent arrives as chroma 0 at lightness 0, anchored at 950.
Pinning the anchor at the far end flattens the ramp
Anchor #e8f7ff at step 950 and one arm has nowhere to go: lightness spans 0.004 and two rows repeat the hex above them.
Token names are rewritten to valid identifiers
The name must work as a custom property, an SCSS variable and a JSON key. My Color 1 becomes my-color-1; 1brand gains an underscore, since $1brand is not valid SCSS. Step keys stay quoted.
Common errors
`blurple` is not a valid color — expected hex (3/4/6/8 digits), rgb(), hsl(), oklch(), or a CSS color name.- One value in the CSS grammar. Uppercase spellings pass and oklch(0.5 1e999 30) lands here too: it yields an infinite chroma.
Lightness range 0.9 to 0.2 is not usable — both ends must sit between 0 and 1, and the darkest end must be lower than the lightest.- The ends are the lightness of step 950 and of step 50, and a restored permalink can carry them swapped. Sorting silently would number tints as shades.
Color is 257 characters — larger than the 256-character limit for a single color.- No color literal needs 256 characters, so a longer one is refused, not truncated. The banner prints this cap beside the command line below.
Token name is 65 characters — larger than the 64-character limit for a token family name.- Names are capped separately at 64 characters, and every token repeats the family name eleven times over.
`🎨🎨` has no letters, digits, `-` or `_` to build a token name from — try something like `brand`.- Sanitizing tries first: accents are stripped and punctuation becomes dashes. A name with nothing left is refused rather than defaulted.
FAQ
Why is OKLCH better than HSL for generating shades?
Because equal steps in OKLCH's L look equal on screen. Two colors at HSL 50% lightness can differ by a factor of eight in contrast against white.
Does the ramp include my exact brand color?
Yes. The anchor step carries your lightness, chroma and hue unchanged, so that hex appears in the export as pasted. Auto picks the nearest step.
What does the mapped label on a step mean?
That the step's coordinates fell outside sRGB and the color moved to the nearest one a hex can express. The count repeats in a note.
Are these the same values Tailwind ships?
No. The 50 through 950 numbering is the convention, so exports drop into a config without renaming, but the eleven lightness targets are this tool's own.
How many shades should a ramp have?
Eleven are generated because that is what this numbering names, and the export is plain text — delete the rows you do not use.
What are the two numbers next to each swatch?
WCAG 2 contrast ratios for that step against white and against black, to two decimals. Judging a pair against a threshold is the contrast checker's job.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Rebuild the ramp from the current controls.
- ⌘/Ctrl + C
- Copy the export when nothing is selected; otherwise the selection.
- ⌘/Ctrl + Shift + C
- Copy the export despite a selection.
- ⌘/Ctrl + S
- Download the export, overriding the browser dialog.
- t
- Advance the theme palette; ignored while typing.
- ? or ⌘/Ctrl + /
- Show the shortcut sheet for this page.
- Esc
- Dismiss the sheet or the copy confirmation.