How to use the palette contrast matrix
- Paste your colors, one per line. Write a name before a colon if you like, such as Ink: #112019. Hex, rgb(), hsl() and oklch() are accepted.
- Read the headline for how many pairs reach the level for body text, and the highest and lowest contrast.
- Use the matrix to look up any pair. Each cell shows the ratio and its level.
- Use the ranked list to pick pairs that work for text, large text or interface parts, and download either table as a CSV.
Formula
linear channel = ((c + 0.055) / 1.055)^2.4 (or c / 12.92 for dark values)
L = 0.2126 R + 0.7152 G + 0.0722 B
ratio = (lighter L + 0.05) / (darker L + 0.05)
The ratio runs from 1 to 21. Levels: 7 or more is AAA for body text, 4.5 or more is AA, and 3 or more is enough for large text and interface parts. Ratios are cut off at two decimals, never rounded up.
An eight color site palette
For the starting palette, Ink (#112019) on White (#FFFFFF) has a ratio of 16.87 and Ink on Page (#FAFAF6) 16.12, both AAA. Red (#B4233C) on White is 6.46, AA, and Blue (#0B57D0) on White is 6.38, AA. Ink on Brand (#25A86B) is 5.53, AA.
Brand on White is only 3.04, so it is suitable for large text and interface parts, not body text. Red and Blue against each other score 1.01, which shows that two colors can look different yet have almost no contrast. Of the 28 pairs, 10 reach 4.5 and 2 reach 7. Black on white is 21.
Checking a whole palette at once
Checking pairs one at a time makes it easy to miss a combination that a designer or a page later puts together. A matrix shows every pairing in one view, so you can mark which colors may sit on which backgrounds before building a design system. Rules like "text color 3 only on backgrounds 1 and 2" come straight from the table.
The ratio is the same whichever color is the text and which is the background. Only the level you need changes with the use: body text, large text or a graphic part.
What contrast does not cover
A passing ratio is necessary but not sufficient for readable text. Font size and weight, line spacing, the actual background (an image or a gradient), and the viewer's vision all matter. Color alone should not carry meaning. Use the Color Contrast Checker for a single pair with suggested fixes, the Color Blindness Simulator to see colors as others do, the Color Palette Generator to build a set, and the OKLCH Color Converter to adjust lightness evenly.
Assumptions and limits
- Colors are read as sRGB. Colors outside sRGB are clipped to it, and alpha is ignored.
- Between 2 and 12 colors are accepted. Names before a colon are used as labels.
- Ratios use the WCAG 2 relative luminance formula. Other contrast methods can give different results.
- The levels follow the usual WCAG ratios of 3, 4.5 and 7, which you can compare with your own requirements.
Frequently asked questions
What do the levels mean?
AAA means a ratio of 7 or more, which suits body text. AA means 4.5 or more. Large only means 3 or more, which suits large text and interface parts but not small text. Fail means under 3.
Why are ratios cut off rather than rounded?
A ratio of 4.499 does not meet 4.5, and rounding would show it as 4.50. Cutting off at two decimals keeps the displayed level honest.
Does the order of the two colors matter?
No. The ratio uses the lighter and the darker luminance, so it is the same whichever color is the text. The table repeats each pair on both sides of the diagonal for easy lookup.
Can I use named CSS colors like red?
No. Use a hex code, rgb(), hsl() or oklch() value. A name before a colon is only a label for the row.