← All guides

Color ramps: how to build an even scale of shades

How to build a color ramp with even steps: lightness in OKLCH, chroma curves, hue drift, how many steps to use and how to check one, with CSS examples.

By Alejandro Vasquez · · 5 min

A color ramp is a row of shades of one color, from light to dark, such as the 50 to 900 steps in a design system palette. Backgrounds use the lightest steps, borders and hover states the middle ones, and text the darkest. If the steps are uneven, one shade looks like a mistake and every component that uses it inherits the problem.

What makes a ramp even

  • Lightness changes by the same amount at every step. In a perceptual space such as OKLCH, equal numbers look like equal steps. In HSL they do not: a yellow and a blue at 50% lightness are very different in brightness.
  • Chroma (how strong the color is) follows a smooth curve: close to grey at the lightest and darkest ends and strongest in the middle.
  • Hue stays put, or drifts slowly in one direction. Yellows that warm toward orange as they darken are a classic example.

How many steps

Nine to eleven is plenty: 50, 100, 200 up to 900, and 950 if you need a near-black. More steps than jobs just invites guessing. Give every step a job, such as 100 for subtle backgrounds, 500 for the brand color and 700 for text on light backgrounds.

How to check a ramp

  • Stack the shades side by side with no gaps. A bad step shows as an edge that looks harder or softer than its neighbors.
  • Squint or blur the screen. Uneven lightness is easier to see when the detail disappears.
  • Convert the ramp to greyscale: the greys should march evenly from light to dark.
  • Test the pairs you will really use for contrast. For example, 700 on 50 should pass WCAG AA for text.
💡 When one step looks off, fix its lightness first. Most broken ramps are a lightness problem, and chroma and hue faults only show once the lightness is right.

In CSS

OKLCH works in all current browsers. A ramp is a list of custom properties that share a hue and follow one chroma curve, with lightness dropping by the same amount each time:

:root {
  --blue-100: oklch(0.93 0.04 255);
  --blue-300: oklch(0.77 0.11 255);
  --blue-500: oklch(0.61 0.15 255);
  --blue-700: oklch(0.45 0.11 255);
  --blue-900: oklch(0.29 0.05 255);
}

In Figma

Create the shades as color variables in one collection, named by step (blue/100 to blue/900). A plugin can generate a ramp from a single color, but always compare the result with the shades on either side, and bind components to the variables rather than to raw values.

Practice

Ramp Repair shows you nine shades of one color with one of them broken. Find it before your lives run out. The fault gets smaller every level and moves from lightness to chroma and hue.

Open the tool: Ramp Repair →

More guides