The eleven rectangles of slightly-different blue

Every brand guideline document has the same page. One logo, a row of rectangles marching from near-black to near-white, and a caption like 'primary color and permitted variations.' Nobody reads the caption twice. But every designer who receives that PDF eventually needs those rectangles as actual values — a button hover that is one step lighter, a chart series that needs five distinguishable blues, a dark mode that asks what the brand's color even means when everything around it inverts.

Building that page by hand is a rite of passage nobody enjoys. You open a color picker, drag the lightness slider, squint, drag again, write down a hex, wonder whether step 4 and step 5 are actually distinguishable, and repeat until the rectangles look evenly spaced to your eye — which is to say, until you stop noticing the unevenness. It works. It is also twenty minutes of imprecise labor that a formula does better in one.

This generator builds the ladder from any color you give it: ten tints toward white, ten shades toward black, every step computed with exact per-channel math and copyable as CSS variables. Type a hex code, get the page from the brand PDF — and, more usefully, get the reasoning behind each step, because knowing why step 40 works on step 90 backgrounds is what separates a color scale from a color decoration.

Building a ladder in thirty seconds

  1. Enter your base color

    Type a hex code, paste one from a brand guideline, or pull it from a photo with the Image Color Extractor first. The ladder regenerates the instant the value changes.

  2. Set the step count and size

    Ten steps at 10% each is the default. Fewer, larger steps read cleaner for small projects; more steps give a design system room to breathe. The preview updates live.

  3. Read the ladder both directions

    Tints run toward white, shades toward black, tones toward gray — three tabs over the same base color. Watch which direction the hue drifts as you go; blues are the usual offenders.

  4. Check contrast as you go

    The tool shows the contrast ratio of white and black text against each step. If your text color fails on your chosen background step, the fix is usually one step away rather than a new base color.

  5. Export in your format

    Copy the whole ladder as CSS custom properties --scale-50 through --scale-900, as a plain hex list for design tools, or as JSON for design tokens. One click each.

The arithmetic of tints and shades

The math is per-channel linear interpolation, and it is worth knowing cold because it explains everything the ladder does. A tint at strength t moves each channel toward white's 255: new value = current + (255 − current) × t. A shade at strength s moves each channel toward black's 0: new value = current × (1 − s). A tone mixes toward gray, usually #808080, with the same interpolation pattern.

Notice what these formulas imply. Because blue channels in saturated colors already sit near 255, tints barely change them — blue climbs from 246 to 248 at a 20% tint — while red, far from its ceiling, leaps from 59 to 98. The channel with the most headroom moves the most. That asymmetry is not a flaw; it is simply what mixing in sRGB does, and it is why tinted colors keep their hue identity while lightening. It is also why the hue drifts a little, since the three channels never move in lockstep.

The alternative school mixes in HSL instead: keep hue and saturation fixed, walk lightness toward 100%. The results are similar in spirit and different in the digits — a 20% sRGB tint of our example blue is #629BF8, while raising HSL lightness from 60% to 70% gives #6DA2F8. Same color family, visibly different swatches side by side. Neither is wrong. The sRGB route is what mix() in CSS does, what this generator does by default, and what most brand guidelines quietly assume; the HSL route keeps saturation at full blast, which can read as artificially vivid at the light end.

The modern option is CSS color-mix(), which interpolates in whatever color space you name — srgb, oklab, oklch, and friends. color-mix(in srgb, #3B82F6 80%, white) reproduces the 20% tint exactly. The perceptual spaces trade a little punch for steadier hue across the ladder. If your team argues about which is correct, the honest answer is that sRGB mixing matches four decades of brand-guideline practice, and OKLCH mixing matches human perception better — pick one per project and stay consistent.

One blue, every value, no rounding surprises

Here is the complete ladder for #3B82F6 — RGB (59, 130, 246) — at 20% steps, every value computed with the formulas above and rounded to whole channels. This is the exact output the generator produces for this input.

StepTint (toward white)Shade (toward black)Tone (toward gray)
Base#3B82F6#3B82F6#3B82F6
20%#629BF8#2F68C5#4982DE
40%#89B4FA#234E94#5781C7
60%#B1CDFB#183462#6481AF
80%#D8E6FD#0C1A31#728098
100%#FFFFFF#000000#808080
The full 3-way ladder for #3B82F6, computed per-channel at 20% steps
Where each end of the ladder earns its place

Input

Base color #3B82F6, used as-is for primary buttons

Output

Tint #89B4FA (40%) for hover states and focus rings; tint #D8E6FD (80%) for informational backgrounds; shade #2F68C5 (20%) for pressed states; shade #183462 (60%) for text on light backgrounds; tone #6481AF (60%) for charts that must not compete with the primary

Walk one cell by hand to see the machine at work. The 40% tint of green: 130 + (255 − 130) × 0.4 = 180, which is B4 in hexadecimal. Red: 59 + 196 × 0.4 = 137.4, which rounds to 137, hex 89. Blue: 246 + 9 × 0.4 = 249.6, rounds to 250, hex FA. The rounding matters at the light end of dark channels — a blue channel at 246 has only 9 units of headroom, so tint steps of 1.8 units each are at the edge of what whole channels can express.

/* The exported ladder, as the generator writes it */
:root {
  --brand-50:  #D8E6FD;
  --brand-100: #B1CDFB;
  --brand-200: #89B4FA;
  --brand-300: #629BF8;
  --brand-400: #3B82F6; /* base */
  --brand-500: #2F68C5;
  --brand-600: #234E94;
  --brand-700: #183462;
  --brand-800: #0C1A31;
}

The contrast ledger: every step, both text colors

WCAG contrast is symmetric — the ratio between #3B82F6 and white is the same number whether the blue is the background with white text on it or the text color on a white background. That symmetry means one table answers both questions for the whole ladder: how each step scores as a background under white text, and how it scores as text on a white background. Every value below is computed with the WCAG relative-luminance formula, rounded to two decimals.

StepHexvs whitevs blackAA normal (4.5:1)
Tint 80%#D8E6FD1.2616.66Black text only
Tint 60%#B1CDFB1.6212.99Black text only
Tint 40%#89B4FA2.119.97Black text only
Tint 20%#629BF82.787.56Black text only
Base#3B82F63.685.71Black text passes; white passes large text at 3:1
Shade 20%#2F68C55.373.91White text passes; black passes large only
Shade 40%#234E948.112.59White text passes
Shade 60%#18346212.311.71White text passes
Shade 80%#0C1A3117.391.21White text passes
One crossover band exists around the base and shade 20% — everywhere else, exactly one text color passes normal-text AA

The ledger exposes the pattern worth memorizing: every step of the ladder has exactly one compliant text color, except the narrow band where the base and its first shade sit. That band is where interface colors live — buttons, links, badges — and it is exactly where the base's 3.68 ratio strands white text below normal-text AA while black text squeaks by at 5.71. Move the fill one shade darker to #2F68C5 and white text jumps to 5.37 and passes; move the fill one tint lighter and black becomes the only option. Ladder-based design systems encode this as a rule: text sits at least two steps away from its background, in either direction.

Read as text colors on a white page, the same numbers flip roles. The base blue at 3.68 fails for body copy; shade 20% at 5.37 passes with margin; shade 40% at 8.11 and shade 60% at 12.31 are heading-grade darkness. A useful sanity check before any audit: compute the ratio of your brand anchor against white once, and you immediately know whether the brand color can be a text color at all or must remain a surface and accent color forever.

When ladders misbehave

The formula is deterministic, which means its failure modes are deterministic too. These are the ones that bite in production:

  • Blue-to-purple drift. Mixing toward white in sRGB shifts saturated blues toward violet, because the blue channel saturates while red keeps climbing. If the drift offends, regenerate with OKLCH-style mixing or hand-correct the two lightest steps.
  • Indistinguishable light steps. Near white, 10% tint steps differ by two or three RGB units — invisible on most screens. At the light end, use bigger steps or accept that steps 90 and 100 are decorative twins.
  • Muddy dark tints. Colors with low saturation produce shades that all converge to the same gray-black. A beige's shade ladder is a study in brown; consider a tone ladder or a second hue for dark-mode accents.
  • Contrast cliffs. White text that passes on the base can fail on one lighter tint — 3.7 to 1 drops below 3 to 1 after a single 20% tint step. Check the ratio at every step you plan to put text on, not just the ones you plan to look at.
  • Dark mode is not an inverted ladder. The shade end of a light-theme scale becomes the background tier in dark mode, but brand colors usually need their own dark-mode anchor — often one or two tints lighter than the light-theme base — rather than a reuse of the same ladder in reverse.
  • Step-count mismatch with neighboring scales. If your blue ladder has 11 steps and your red ladder has 10, any UI that pairs them by index will be subtly off. Keep the count and the spacing identical across every color in the system.

A destructive-action palette, worked from one anchor

Take the pattern from theory to a shipped feature. A checkout flow needs a destructive-action color, the designer hands over one anchor — #E11D48, RGB (225, 29, 72) — and every state below comes off the ladder at 20% steps, each contrast value computed with the WCAG formula:

RoleValueLadder stepText or pairingContrast
Primary destructive button#E11D48BaseWhite text4.70:1 — passes AA normal with 0.2 to spare
Button hover#B4173AShade 20%White text6.72:1 — darkening on hover buys margin
Button pressed#87112BShade 40%White text9.79:1
Focus ring#E74A6DTint 20%On white page3.75:1 — clears the 3:1 indicator threshold
Danger banner background#F9D2DATint 80%Body text #5A0C1D10.14:1 — tint-80 background, shade-60 text
Destructive link on white#B4173AShade 20%As text color6.72:1 — the base at 4.70 passes, the step has margin
Six production roles, one anchor, every value a ladder step — with the contrast audit already done.

The row that teaches the most is the hover. The instinct is to lighten a filled button on hover, but lightening to the 20% tint drops white text from 4.70:1 to 3.75:1 — below the 4.5:1 bar for normal-size labels. Darkening to the 20% shade moves the same interaction to 6.72:1, so the hover gets both a visible state change and a compliance cushion. The tint end is not wasted either: the 80% tint with the 60% shade as text is a 10.14:1 banner that stays unmistakably in the anchor's hue family.

The dark-mode split, worked from the same anchor

Dark mode is where a one-directional palette dies and a ladder pays rent. Inverting the light theme fails because the shade end of the ladder was built for text, not for surfaces — but the same generated values recombine into a dark theme with almost no new colors. Here is the full split for the #3B82F6 ladder, with the ratios verified against the WCAG formula.

Dark-mode roleValueSource stepContrast on the background
App background#0C1A31Shade 80%—
Elevated surface (cards)#3D485A20% tint of shade 80%—
Body text#D8E6FDTint 80%13.79:1
Headings#B1CDFBTint 60%10.76:1
Links and interactive#89B4FATint 40%8.26:1
Focus rings, borders#629BF8Tint 20%6.26:1 on the background, 3.33:1 on card surfaces — clears the 3:1 non-text minimum either way
Chart series, muted labels#4982DETone 20%Sits behind text without competing
Every dark-mode value is a step the light-mode ladder already generated

Two construction details carry the scheme. The elevated surface is a 20% tint of the background shade rather than a neutral gray, so cards stay in the brand's hue family instead of reading as pasted-on concrete — the difference between a dark theme and a merely darkened one. And the interactive color moves two tints up from the base, because #3B82F6 against #0C1A31 lands at 4.73:1, which technically passes normal text but reads muddy next to true white body copy; #89B4FA at 8.26:1 keeps links visibly bluish and comfortably compliant.

The mapping also explains a naming convention: export the ladder once as --brand-50 through --brand-800, and the dark theme consumes the same variables with different role assignments — light mode spends the dark steps on text, dark mode spends the light steps on text. One ladder, two themes, zero colors invented under deadline pressure.

The people who live in this tool

Color ladders are infrastructure, and infrastructure has a maintenance staff:

  • Design system engineers — turning one brand color into a scale of tokens with names like blue-500 and blue-700
  • Brand managers — producing the 'permitted variations' page of the guideline PDF in a minute instead of an afternoon
  • Front-end developers — filling in missing hover, focus, active, and disabled states with principled values instead of eyeballed ones
  • Data visualization designers — building distinguishable series colors from a single brand anchor when the brand allows only one hue
  • Accessibility auditors — finding the nearest passing step for a text-on-background combination without abandoning the palette
  • Freelancers — delivering a professional-looking color system alongside a logo they were handed last Tuesday

The pattern uniting them: one authoritative color, many required variants, zero appetite for inventing each variant by taste. The ladder is how a single brand decision scales into dozens of interface states without drifting into fifty shades of consensus-by-committee.

Tints, shades, and tones — the honest comparison

Three directions from the same anchor, and a real reason to care which one you are walking:

Mixed withGetsBest used for
TintWhiteLighter, airier, hue intactBackgrounds, hover states, highlights
ShadeBlackDarker, heavier, more seriousText, pressed states, depth cues
ToneNeutral grayMuted, calmer, less saturatedCharts, secondary UI, anything that must not compete with the brand color
Same anchor, three destinations — 20% from #3B82F6: #629BF8, #2F68C5, #4982DE

The underused member of the family is the tone. Teams reach for tints and shades automatically and then wonder why their dashboards scream — five tints of brand blue all at full saturation will out-shout every number on the screen. Tones are the volume knob. A 60% tone of most brand colors sits comfortably behind data and still reads unmistakably as the brand, which is why mature visualization palettes lean on them.

One hidden constant in the tone column deserves daylight: the gray it mixes toward is #808080 — RGB (128, 128, 128), the exact midpoint of each channel, not a luminance-matched gray. The 20% tone of the example blue proves it: green sits at 130, two units above gray, and 130 + (128 − 130) × 0.2 = 129.6, which rounds back to 130 — the green channel barely moves because it is already gray. Red travels 59 → 73, blue falls 246 → 222, and the result, #4982DE, keeps roughly the lightness of the anchor while surrendering its saturation. That is the tone's job description: same seat at the table, lower voice.

And the comparison that matters at export time: mixing in sRGB versus mixing in HSL versus mixing in a perceptual space. The generator's default matches sRGB channel mixing — the same values color-mix(in srgb, ...) produces and the same values most brand guidelines were built on by hand. HSL lightness produces punchier light steps; OKLCH produces the steadiest hue. All three are one click apart here, and the ability to compare them on the same base color is the fastest education in color math we know of.

Not much to upload, and nothing is

This tool does not even need your images. It operates on six hexadecimal digits you type — the ladder is arithmetic on three numbers, performed in the page and rendered as swatches. There is no file to process, no pixel data to read, and consequently no privacy surface at all.

The color you type never leaves the tab in any form we could read, because the computation is local JavaScript and the output is DOM elements on your screen. If you arrived from the Color Picker from Image with a hex code you pulled from a client photo, the trail ends here: photo processed locally, code typed locally, ladder generated locally. For something that touches brand systems worth real money, that closed loop is quiet, boring, and exactly right.

Ladder questions, answered

What is the difference between a tint and a shade?

A tint is a color mixed with white; a shade is the same color mixed with black. The direction matters more than the words: tints lighten while keeping the hue, shades darken it. Tones — the third term in the family — mix with neutral gray instead, muting the color without making it meaningfully lighter or darker.

How is a 20% tint calculated?

Each RGB channel moves 20% of the way toward white. For #3B82F6, red goes from 59 to 59 plus 20% of (255 minus 59), which is 98; green goes from 130 to 155; blue barely moves, from 246 to 248. The result is #629BF8. The same interpolation in the other direction, toward black, gives a 20% shade: #2F68C5.

How many steps should my color ladder have?

Ten is the practical default — enough range for hover states, borders, backgrounds, and chart series without inviting decision fatigue. Design systems that scale often use 11 steps so there is a true middle. What matters more than the count is coverage: one value light enough for backgrounds and one dark enough for text on those backgrounds, with enough steps in between that adjacent values stay distinguishable.

Can I export the ladder for my codebase?

Yes — the generator outputs CSS custom properties, one variable per step, named in a scale pattern like --brand-50 through --brand-900. The block copies with one click and pastes straight into a stylesheet or a Tailwind config. Hex list and JSON exports are there too for design tools and design tokens pipelines.

Why do my blue tints look like they drift toward purple?

Because mixing toward white in sRGB moves channels at different rates, and blue's channel is usually already near its ceiling. The blue channel saturates early while red keeps climbing, which shifts the mixture's apparent hue slightly toward violet as the ladder lightens. It is a known property of mixing in gamma-encoded sRGB; perceptual color spaces like OKLCH keep hue steadier, and CSS now supports color-mix(in oklab, ...) for exactly this reason.

What color should I start my ladder from?

Start from your brand's anchor color — the one already on buttons and links — and treat it as the middle of the ladder rather than the darkest step. If you are building from a photograph instead, pull the dominant colors with the Image Color Extractor first, choose one as the anchor, and generate the ladder here. Anchor in the middle leaves room for both darker text-ready shades and lighter background-ready tints.

Does white text pass accessibility checks on my color?

It depends on the step, and the arithmetic is unforgiving. White text on #3B82F6 yields a contrast ratio of about 3.7 to 1 — fine for large text, below the 4.5 to 1 required for normal text. One shade darker, on #2F68C5, the ratio rises to about 5.4 to 1 and normal text passes. That jump is why ladders exist: the fix for a failing combination is usually one step, not a redesign.

Which step should body text use on a white background?

Two shade steps past the base, minimum. For #3B82F6, the base itself scores 3.68:1 against white and fails normal-text AA; shade 20% (#2F68C5) reaches 5.37:1 and passes; shade 40% (#234E94) at 8.11:1 and shade 60% (#183462) at 12.31:1 are the comfortable body-text and heading grades. If the brand color must be text on white and its ratio is under 4.5, the ladder's shade end is the compliant version of that color.

How do I put the ladder into a Tailwind config?

Extend the theme with a nested object: colors: { brand: { 50: '#D8E6FD', 100: '#B1CDFB', 200: '#89B4FA', 300: '#629BF8', 400: '#3B82F6', 500: '#2F68C5', 600: '#234E94', 700: '#183462', 800: '#0C1A31' } }. Classes then read naturally — bg-brand-50 for tinted backgrounds, text-brand-700 for dark text, ring-brand-200 for focus rings. Keep the step numbers aligned across every color in the system so paired hues sit at consistent darkness.

Do these tint percentages match print ink tints?

No, and conflating the two causes reprints. A print tint is ink coverage — a 40% tint of a spot color means 40% ink density on press — while an RGB tint is additive-light channel math. A 40% screen tint of a Pantone blue and the 40% RGB tint of its hex approximation land on visibly different colors, and CMYK conversion shifts both again. Build the ladder for screens here; ask the print designer to generate the ink-tint percentages from the Pantone book for paper.

Is a 20% tint the same as drawing the color at 80% opacity?

Yes, on a white background — the two are the same arithmetic. Compositing at 80% opacity over white computes 0.8 × channel + 0.2 × 255 per channel, which is identical to the tint formula channel + (255 − channel) × 0.2. Draw #E11D48 at 80% alpha on white and you get #E74A6D, the 20% tint, exactly. The equivalence breaks the moment the underlying background is not white: opacity composites with whatever is underneath, while the tint value is fixed forever.

How is the WCAG contrast ratio actually computed?

Two steps. First, relative luminance: linearize each channel — c ÷ 255, then ((c + 0.055) ÷ 1.055)^2.4 — and combine as 0.2126 R + 0.7152 G + 0.0722 B. For #3B82F6 that gives 0.2126 × 0.0437 + 0.7152 × 0.2232 + 0.0722 × 0.9216 = 0.2355. Second, the ratio: (lighter + 0.05) ÷ (darker + 0.05), so against white it is 1.05 ÷ 0.2855 = 3.68. That 3.68 is why the base blue fails for body text and its 20% shade, at 5.37, passes.

How does a color ladder fit the 60-30-10 rule?

The rule splits a screen's visual weight: about 60 percent neutral background, 30 percent secondary surfaces, and 10 percent accent. The ladder's job is the 10 percent — the base and one or two steps supply buttons, links, and highlights — plus the text tiers that sit on the neutral 60. Where teams go wrong is spending ladder steps on the background itself; five tints of brand blue as page furniture leaves nothing at full strength for the actions that matter.

Tools that feed and follow the ladder

The ladder sits in the middle of a small color workflow:

  • Image Color Extractor — upstream: pull the anchor color from a photograph or logo when no brand value exists
  • Color Picker from Image — upstream alternative: grab one exact pixel's hex when you know the spot
  • Duotone Image Maker — downstream: put two ladder values to work as a two-color treatment on real imagery

The loop closes nicely: extract, ladder, apply, and when the photography changes next season, the whole chain regenerates from a single new anchor color. That is the difference between a palette that is maintained and a palette that is survived.

Sources and further reading

Sources and further reading

We cite primary sources (standards bodies, government agencies, official documentation) wherever they exist so you can verify every number on this page yourself.