Color Contrast Grid
Paste a palette and see at once which colour pairs are readable, as text and as UI.
Try before you buy.
- Free preview: every count for your palette and the first half of the grid and of the combinations list (up to 10 rows each); the rest stays locked.
- Locked until you unlock it: download and copy.
- Unlock: Pro pass, ₹179 for 30 days, a one-time payment that never renews.
Ways to unlock shows how to get the full result.
Printing this result is locked in the free preview.
Your palette
HEX, rgb(), hsl(), oklch(), lab() or CSS names, before or after a name. You can also paste CSS custom properties (--brand: #1d5fcb;), SCSS variables, JSON tokens or the
colors object of a Tailwind config. Up to 40 colours.
Contrast grid
Rows are text colours, columns are backgrounds. Each cell shows “Aa” in the text colour on the background, with its ratio and the best level it reaches.
Combinations
Locked in the free preview. Opens the ways to unlock this result.
Locked in the free preview. Batch runs unlock with a pass.
Locked in the free preview. Query results unlock with a pass.
About the Color Contrast Grid
Check a whole palette for readable colour pairs at once. Paste your colours and the grid puts every colour on every other one: each cell shows “Aa” in the text colour on the background, its contrast ratio and the best WCAG 2.2 level the pair reaches — AAA (7:1), AA (4.5:1), AA large (3:1, which is also the minimum for icons, borders and other interface graphics) or a fail.
It reads the formats design systems are kept in: a plain list with names, CSS custom properties (with var() references between them), SCSS or Less variables, JSON tokens and the colors object of a Tailwind config. Filter the grid to the pairs that pass a level, swap rows and columns, and read the combinations sorted from highest to lowest contrast. With a pass, the grid and the combinations list go into your documentation as Markdown, CSV or a PNG image. Everything runs in your browser.
How to use it
- Paste your palette into Your palette, one colour per line, with an optional name before or after it (
Brand #1d5fcb,--brand: #1d5fcb;,brand: "#1d5fcb"). The examples show the three main formats. - Tick Add white and black to see every colour on pure white and black as well.
- Read the grid: rows are text colours and columns are backgrounds (Swap rows and columns turns it round). The tag in each cell gives the ratio and the best level.
- Choose Show 3:1+, 4.5:1+ or 7:1+ to keep only the pairs that pass that level; the combinations list below follows the same choice.
- With a Pro pass, use Copy table, CSV, Markdown or PNG to put the accessible combinations into your design-system documentation; in the free preview those buttons are locked.
Examples
White #ffffff · Ink #0f172a · Brand #1d5fcb · Accent #f97316
12 combinations: Ink on White 17.85:1 (AAA) · Brand on White 5.91:1 (AA) · Accent on Ink 6.36:1 (AA) · Brand on Ink 3.01:1 (AA large) · Accent on White 2.80:1 (fail) · Accent on Brand 2.10:1 (fail).
Orange on white fails even for large text, so it suits a fill behind dark text better than text on white.
Grey #777777 on White #ffffff
4.47:1 — fails AA for normal text. #767676 on white is 4.54:1 and passes.
WCAG thresholds are exact: a ratio of 4.478 is not rounded up to 4.5. The grid truncates every ratio to two decimals.
Black #000000 on Brand at 50 % (#1d5fcb80)
9.41:1 (AAA): the tint is first painted over white, which gives #8eafe5.
Common uses
- Documenting which text and background pairs a design system allows, with the ratios to back it up.
- Checking a new brand palette before it goes into a product, a slide template or a website theme.
- Auditing a Tailwind or CSS-variables theme for pairs that fail AA, before an accessibility review.
- Finding which colours are safe for icons, input borders and focus rings (3:1) and which only work as backgrounds.
How the ratio is worked out
Each colour’s relative luminance comes from its sRGB channels, as WCAG 2.2 defines it: every 8-bit channel is divided by 255, channels at or below 0.04045 are divided by 12.92 and the others become ((c + 0.055) / 1.055)^2.4, and then L = 0.2126 R + 0.7152 G + 0.0722 B.
The contrast ratio is (L1 + 0.05) / (L2 + 0.05), with L1 the lighter colour, from 1:1 (no contrast) to 21:1 (black on white). The ratio is the same whichever colour is the text, so the grid is mirrored across its diagonal unless a colour is translucent.
WCAG treats its thresholds as exact: a computed ratio is not rounded before it is compared, so 4.499:1 does not meet 4.5:1. The grid shows ratios truncated to two decimals, never rounded up.
Which level a pair needs
- AA, normal text: 4.5:1 (SC 1.4.3).
- AA, large text: 3:1. Large text is at least 18 point (about 24 CSS pixels), or 14 point (about 18.5 pixels) when bold.
- AAA: 7:1 for normal text and 4.5:1 for large text (SC 1.4.6).
- Interface components and graphics: 3:1 against what is next to them (SC 1.4.11) — icons that carry meaning, input borders, focus indicators, chart lines.
Logos and the text of disabled controls have no contrast requirement. The badge in each cell names the highest level the pair reaches; “AA large” covers both large text and interface graphics.
Formats it reads
- A list:
Brand #1d5fcb,#1d5fcb Brand,Brand: #1d5fcb, Markdown table rows, numbered or bulleted lists, several colours on one line. - Colour values: HEX with or without
#(3, 4, 6 or 8 digits),rgb(),hsl(),hwb(),oklch(),oklab(),lab(),lch(),color(display-p3 …)and the 148 CSS colour names. - CSS custom properties such as
--color-primary: oklch(52% 0.2 264);, includingvar(--other)references within the paste; a leadingcolor-is dropped from the name. - SCSS and Less variables:
$brand: #1d5fcb;,@brand: #1d5fcb;. - JSON tokens and Tailwind configs: nested keys become names (
brand.500→brand-500,DEFAULTdropped), and a design token’s$value(W3C Design Tokens format) orvalue(Style Dictionary) is read under the token’s own name. Only string values are read; code such ascolors.blueor functions is skipped, never run.
The same colour listed twice is shown once, with both names.
Translucent and wide-gamut colours
A translucent text colour is painted over each background before its contrast is measured, as a browser paints it. A translucent background is painted over white, which WCAG assumes when no background is given. A colour outside sRGB (color(display-p3 …) or a vivid oklch()) is first mapped to the nearest displayable colour with the CSS Color 4 gamut-mapping algorithm, because WCAG’s luminance formula is defined for sRGB.
Limitations
- Contrast ratio is only one part of readability: font weight, size, spacing and the colours around a pair also matter. The ratios are for flat colours; text over an image or a gradient needs a check against the lightest and darkest areas behind it.
- The grid uses the WCAG 2.2 formula. The APCA method proposed for future guidelines gives different numbers and is not part of WCAG 2.2.
- Up to 40 colours are compared (1,560 combinations); paste the rest separately.
- In the free preview the grid and the combinations list show their first half (up to 10 rows each) and every count, and the exports stay locked.
Privacy
Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.
Frequently asked questions
What do I get without a pass?
Without a pass, Color Contrast Grid shows every count for your palette and the first half of the grid and of the combinations list (up to 10 rows each); the rest stays locked. Until you unlock it, the result can’t be downloaded or copied. A Pro, Premium or Ultimate pass, a one-time payment that never renews, unlocks the full result. The pricing page lists the passes and their prices.
What contrast ratio does WCAG AA need?
4.5:1 for normal text and 3:1 for large text (at least 18 pt, or 14 pt bold). Icons, input borders and other interface graphics need 3:1 under SC 1.4.11. AAA asks for 7:1 and 4.5:1.
Why is a pair shown as failing when it is “nearly” 4.5:1?
WCAG thresholds are exact and computed ratios are not rounded: 4.478:1 fails AA. Darken the text or lighten the background a little; the Color Contrast Checker suggests the nearest passing colours for one pair.
Can I paste my tailwind.config.js?
Yes — paste the whole file or just the colors object. Nested shades become names such as brand-500. Values that are code rather than strings (colors.blue, functions) are skipped, and nothing in the paste is run.
Is the grid the same both ways round?
For opaque colours, yes: contrast does not depend on which colour is the text. With translucent colours it can differ, because a translucent text colour is painted over the background.
Are my colours uploaded?
No. The palette is read and the grid is worked out in your browser; nothing you paste is sent anywhere.