Skip to content
nearnull

Color Palette Contrast Matrix

Check every text and background combination of a palette at once, with contrast ratios and WCAG AA and AAA results. Runs entirely in your browser. Nothing is sent to any server.

One color per line, in any format. Up to 10 colors; duplicates are merged.

8 of 20 pairs pass AA
Background → Text ↓
#111827
#ffffff
#2563eb
#f59e0b
#e5e7eb
#111827
Aa 17.73:1 AAA
Aa 3.43:1 AA large
Aa 8.26:1 AAA
Aa 14.32:1 AAA
#ffffff
Aa 17.73:1 AAA
Aa 5.16:1 AA
Aa 2.14:1 Fail
Aa 1.23:1 Fail
#2563eb
Aa 3.43:1 AA large
Aa 5.16:1 AA
Aa 2.4:1 Fail
Aa 4.17:1 AA large
#f59e0b
Aa 8.26:1 AAA
Aa 2.14:1 Fail
Aa 2.4:1 Fail
Aa 1.73:1 Fail
#e5e7eb
Aa 14.32:1 AAA
Aa 1.23:1 Fail
Aa 4.17:1 AA large
Aa 1.73:1 Fail

AAA: 7:1 or more. AA: 4.5:1 or more. AA large: 3:1 or more, enough only for large text (24px, or 18.7px bold) and UI components.

What is a contrast matrix?

A contrast matrix checks every color in a palette against every other one, as text and as background, so you can see at a glance which combinations are readable. Each cell shows a sample in that text color on that background, its WCAG 2.x contrast ratio and the level it reaches: AAA from 7:1, AA from 4.5:1, and AA for large text and interface components from 3:1. Instead of checking pairs one by one, you paste the whole palette and get the full picture, which is how design systems document which colors may be combined.

Examples

Checking every pair of a palette in code:

JavaScript
// every ordered pair, skipping a color on itself
for (const text of palette)
  for (const bg of palette)
    if (text !== bg) console.log(text, bg, contrast(text, bg));
Python
from itertools import permutations

for text, bg in permutations(palette, 2):
    print(text, bg, round(contrast(text, bg), 2))
CSS
/* a passing pair from the matrix, as tokens */
:root {
  --text-on-surface: #111827;
  --surface: #e5e7eb;
}

Use Cases

Documenting a design system

Publish which text and background colors may be combined, so nobody has to check contrast again for each new screen.

Auditing a brand palette

Paste the brand colors and find out right away which ones can carry body text and which are for decoration only.

Choosing button and badge colors

Compare candidate fills against white and dark text in one view to pick the ones that work with both.

Charts and data labels

Check which label color stays readable on each series color before placing values inside bars or slices.

Frequently Asked Questions

Why is each pair shown twice?
The ratio is the same both ways, but text and background are different roles. Blue text on white and white text on blue have the same ratio, yet you may only want one of them in your design, so the matrix lists both.
Why are the diagonal cells empty?
They would be each color on itself, which always has a ratio of 1:1 and is never a real combination.
What does AA large mean?
A ratio between 3:1 and 4.5:1 passes WCAG AA only for large text (at least 24 CSS pixels, or about 18.7 pixels bold) and for icons, borders and other interface components. Body text needs 4.5:1.
How are transparent colors handled?
Alpha is ignored and every color is treated as opaque, since a palette entry doesn't say what would be behind it. To check a translucent color on a real background, flatten it first with the HEX Opacity Converter.
Is my data sent to a server?
No. Every ratio is calculated in your browser with plain JavaScript. Nothing you enter is transmitted or stored.