Material Design 3 Tonal Palette
Generate a Material Design 3 tonal palette (tones 0–100) from any source color, with contrast against black/white and CSS/Tailwind/JSON export.
:root {
--primary-0: #000000;
--primary-10: #050013;
--primary-20: #1c0042;
--primary-30: #341767;
--primary-40: #4d3486;
--primary-50: #6851a5;
--primary-60: #856fc6;
--primary-70: #a38de7;
--primary-80: #c1b0ff;
--primary-90: #dfd8ff;
--primary-95: #efecff;
--primary-99: #fcfbff;
--primary-100: #ffffff;
}Tones step OKLCH lightness (not Material's CIELAB L*) and are gamut-clamped to sRGB, so each swatch is darker than the Material 3 tone of the same number.
How to use
- Pick a source color with the picker, or paste a hex code.
- Optionally rename the palette (used in the export prefix, e.g.,
--primary-40). - Choose an export format — CSS custom properties, Tailwind config, JSON design tokens, or SCSS variables — and copy.
- Click any swatch to copy its hex.
About this tool
ShowHide
From one source colour, builds a thirteen-step tonal ramp — 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 99, 100 — in the shape Material Design 3 uses for theming. Each step keeps the source hue, sets the lightness to that step, and pushes chroma as far as the sRGB gamut allows at that lightness, so the palette stays as saturated as the display can actually show rather than being clipped silently. The contrast ratio against whichever of black or white performs better is printed on every swatch.
The point of a tonal ramp is that it makes contrast a matter of subtraction. Material's own guarantee is stated on its tone scale: two tones fifty apart clear 4.5:1, and forty apart clear 3:1 — which is why the system pairs tone 40 with tone 100 for a light theme and tone 80 with tone 20 for a dark one, and why flipping a theme is a matter of swapping tone numbers rather than re-picking colours. Checking that empirically on greys: tones 40 and 90 come out at 5.0:1, 30 and 80 at 5.5:1, 10 and 60 at 5.4:1.
One divergence to know before you paste these into a token file. Material's tone is CIELAB lightness, L*; this tool steps OKLCH lightness instead. Both are perceptual scales and both give an evenly-spaced ramp, but they are not the same numbers: tone 40 here lands near L* 30, and tone 60 here lands near L* 54, so each swatch is roughly one step darker than the Material tone of the same name. Use the ramp for its spacing and read the printed contrast ratio for each pair — do not assume a swatch labelled 40 is interchangeable with Material's tone 40 in an existing theme.
Two further limits. The ends are pinned: tone 0 is black and tone 100 is white regardless of the source hue, which is what makes a ramp from any colour comparable to a ramp from any other. And maximum chroma at a given lightness depends on the gamut, so a palette built here for sRGB will look less saturated than the same tones rendered on a wide-gamut display, where more of the requested colour is actually available.
Frequently asked questions
Is this the same as Google's HCT algorithm?
Close in spirit but not identical. Google's Material Color Utilities use HCT, which is built on CAM16. This tool uses OKLCH (Björn Ottosson, 2020) as a browser-friendly perceptual color space. Tones at the same lightness will look comparable but the exact hex values will differ slightly from material-color-utilities.
Why does the chroma vary between tones?
sRGB can't reproduce highly saturated colors at very dark or very bright lightness — the tool finds the maximum chroma that stays in gamut via binary search. That's why tone 90 (light tint) is washed-out and tone 50 is most vivid for most hues.
How do I read the contrast ratio?
It's WCAG relative-luminance contrast against the better of black or white. ≥4.5 passes WCAG AA for normal text; ≥3.0 passes AA for large text and UI components.
What about dark mode roles?
M3 maps roles like primary to tone 80 in dark mode and tone 40 in light mode, on-primary to tone 20 / tone 100, etc. This tool gives you the raw tonal scale — assigning roles to tones is up to your theme spec.
Related tools
Color Token Exporter
Define a color palette once, export to CSS custom properties, Tailwind config, SCSS, LESS, design-token JSON, SwiftUI Color, or Android colors.xml.
Color & CSS
Color Palette from Image
Drop an image and the tool extracts a dominant-color palette via Canvas — copy HEX or grab the whole set.
Color & CSS
Color Palette Generator
Pick a base color, get classic color-wheel harmonies — complementary, split-complementary, triadic, tetradic, square, analogous, monochromatic.
Color & CSS
Color Shades & Tints Generator
Generate tints (lighter), shades (darker), and tones (with gray) from any base color — 2 to 20 stops, in HEX, RGB, or HSL.
Color & CSS
Color Format Converter
Convert any color between HEX, RGB, HSL, HSV, OKLCH, and a CSS custom property.
Color & CSS
OKLCH Color Picker
Pick colours in the perceptually uniform OKLCH space (lightness · chroma · hue) — and see whether each pick fits inside the sRGB display gamut.
Color & CSS