A 50 to 950 OKLCH scale, copied as CSS variables.

HEX, RGB, HSL, or a CSS color name. Hue is held. Lightness walks 50 to 950.

 
Private ● Runs entirely on your device Runs entirely on your device. Nothing is uploaded.No account required.Nothing stored unless you choose to save it.
▸ More about

Uses of tints and shades

  • Turning one brand hex into a token ramp before a component library is named.
  • Checking whether the stop nearest that brand can carry body text on white.
  • Copying --shade-50 through --shade-950 into a stylesheet without a design-tool account.

tints and shades pitfalls

  • Expecting the hex values to match a Tailwind version.
  • Using a failing brand stop for body text because the swatch looked fine in the row.
  • Keeping full chroma at stop 50 and clipping the hex outside sRGB.

tints and shades questions (10)

How do I generate a 50 to 950 color palette from one hex?

Paste a color such as #3b82f6, or pick one. The page builds eleven stops, from 50 through 950, and shows the CSS custom properties under the row. Copy CSS puts the whole :root block on the clipboard. Tap one stop to copy only that hex. The hue stays the hue you typed. Lightness is what changes from the pale stop to the near-black stop.

What is the difference between tints and shades?

A tint is the color mixed toward white. A shade is the color mixed toward black. In this scale the light stops, 50 through 300, are the tints, and the dark stops, 700 through 950, are the shades. Stop 500 sits near the lightness of the color you typed. The names match the Tailwind ramp people already use in a stylesheet, so a token called --shade-500 reads as the brand step.

Why is the scale in OKLCH instead of HSL?

HSL lightness is not perceptual. A yellow at 50% lightness looks much lighter than a blue at the same number, and a ramp built that way goes muddy in the middle. OKLCH walks lightness in a space where equal steps look closer to equal. Hue is held in degrees. Chroma, the colorfulness, is reduced only when the full amount would fall outside sRGB and the hex would have to be clipped.

Why does a light stop look less saturated than my base color?

A very light color cannot keep a high chroma and still fit inside sRGB. The page binary-searches the largest chroma that stays in gamut at that lightness, then rounds to hex. The hue does not move. If you need the original chroma at every stop, some of those stops are not displayable on a normal screen, and a hex code would be a lie. The reduced stop is the honest one.

When does the note about contrast on white appear?

The stop whose lightness is closest to your color is treated as the brand stop. If that stop, used as text on white, is under 4.5:1, the note names the stop and the ratio. Body text needs 4.5. If the brand stop already clears 4.5, the note stays hidden. A pale yellow brand fails. A deep navy brand usually passes. The other stops are not scored here.

Is this the same as Tailwind color shades?

The stop numbers are the ones Tailwind uses: 50, 100, 200, and so on through 950. The hex values are not a copy of any Tailwind release. Tailwind picks a family by hand and revises it between versions. This page derives every stop from the one color you typed, in OKLCH, so two brands do not share a palette. Use the stop names. Do not expect the hex to match a docs page.

Can I paste rgb(), hsl(), or a CSS color name?

Yes. #3b82f6, rgb(59, 130, 246), hsl(217, 91%, 60%), and names such as teal all parse. The picker writes a six-digit hex back into the field when you change it. Alpha is ignored, because a shade ramp is a set of opaque tokens. If the text is not a color, the scale and the CSS clear and the error line says why.

Does this color scale generator upload my brand color?

No. Parsing, the OKLCH math, and the CSS block all run in the browser after the page loads. There is no account. The color you type is not saved either, so a refresh starts from the default ramp. Runs entirely on your device. Nothing is uploaded.

How should I use the CSS variables?

Paste the :root block into a stylesheet. Then color: var(--shade-700) and background: var(--shade-50) pick two stops from the same hue. The variable names are --shade-50 through --shade-950. They do not include a brand prefix. If you already have a --shade-500 in the project, rename these before you paste, or the later rule wins and the old token disappears.

Does a passing brand stop mean the whole palette is accessible?

No. The note is one pair: the color you typed, which sits at the brand stop, as text on white. A light 50 stop will fail that same test, and a dark 900 stop can fail as a background behind black text. This page does not score every pair. When you need a specific foreground on a specific background, open the contrast checker and type those two hex values. The scale is the ramp. The checker is the verdict.

How to Build a 50 to 950 OKLCH Color Scale All Design & CSS