Contrast Checker
Scores a foreground and background pair against WCAG 2 and APCA and suggests the nearest passing colour.
Checks a text and background pair against both WCAG 2.2 and APCA, simulates the three dichromacies, and can score a whole palette as a matrix. It shows both standards because they disagree on real pairs, and that disagreement is the useful part.
The quick brown fox jumps over the lazy dog. 다람쥐 헌 쳇바퀴에 타고파.
WCAG 2.2
4.54:1
- PASSAA — 1.4.3 Contrast (Minimum), normal textneeds 4.5:1
- FAILAAA — 1.4.6 Contrast (Enhanced), normal textneeds 7:1
- PASS1.4.11 Non-text — icons, borders, focus ringsneeds 3:1
Counted as normal text. Large starts at 24px, or 18.66px at weight 700. This is the standard accessibility law currently references — the EN 301 549 and Section 508 requirements both point at WCAG, so this is the number an audit will use.
APCA
Lc 71.6
Dark text on a light background. The sign is the polarity — unlike WCAG, swapping the two colours changes the answer.
Reaches Lc 60 — fluent text. Readable at size, but not for sustained reading at 16px.
16px at weight 400 is not enough at this Lc.
| Level | at 400 | at 700 |
|---|---|---|
| Lc 90 | 14px | 12px |
| Lc 75 | 18px | 14px |
| Lc 60 | 24px | 18px |
| Lc 45 | 36px | 24px |
| Lc 30 | 48px | 36px |
The two standards disagree, by design
WCAG 2’s ratio is a formula from 2008: a ratio of relative luminances with a fixed flare term, symmetric in its two arguments. APCA models the perceptual response — it is polarity-dependent, because dark text on light genuinely reads better than the reverse at the same luminance difference, and it takes font size and weight as part of the question rather than as a separate rule bolted on afterwards.
So they disagree on real pairs, and the disagreement is not a bug in either. WCAG 2 passes some mid-grey-on-white combinations that are genuinely hard to read, and fails some dark-on-dark ones that are fine. WCAG 2.2 is what accessibility law currently references, so it is the one an audit will run. APCA is the better model of what a reader experiences. Use WCAG to pass, and APCA to decide which of the passing options to pick.
This pair is one of them: WCAG AA says pass and APCA says not adequate at 16px/400.
Colour vision
Simulated with the Viénot–Brettel–Mollon projections, applied in linear light. Applying them to gamma-encoded bytes — the common shortcut — overstates how distinguishable a pair is, which is the wrong direction for an accessibility check to be wrong in.
Sample text
Protanopia (no red cone, ~1% of men) · 4.54:1
Sample text
Deuteranopia (no green cone, ~1% of men) · 4.54:1
Sample text
Tritanopia (no blue cone, ~0.01%) · 4.54:1
Sample text
Achromatopsia (no colour, ~0.003%) · 4.54:1
How to use it
Enter the two colours
Text colour and background, in any notation. The sample paragraph above the verdicts is drawn in them at the size and weight you set.
Set the real size and weight
WCAG changes its threshold at 24px, or 18.66px at weight 700. APCA takes size and weight as part of the question rather than as a separate rule. Neither answer means much at the wrong size.
Read both verdicts
WCAG to pass an audit, APCA to decide between the options that pass. When they disagree the page says so explicitly.
Check the whole palette at once
Paste your colours, one per line, and get an N×N matrix. It is N×N rather than a triangle because APCA is not symmetric — the same two colours score differently depending on which is the text.
Common questions
Which standard should I follow?
WCAG 2.2, because that is what the law references — EN 301 549 and Section 508 both point at it, so it is the number an audit will run. APCA is the better model of what a reader experiences, so use it to choose between the pairs that already pass.
Why do WCAG and APCA disagree?
WCAG 2’s ratio is a 2008 formula: relative luminances with a fixed flare term, symmetric in its arguments. APCA models perception, is polarity-dependent — dark on light genuinely reads better than the reverse — and takes size and weight into account. So WCAG passes some mid-grey-on-white that is hard to read, and fails some dark-on-dark that is fine.
Why is the colour-vision simulation different from other tools?
Because it is applied in linear light. The common shortcut is to run the projection on gamma-encoded bytes, which makes pairs look more distinguishable than they are — the wrong direction for an accessibility check to be wrong in.
Does passing contrast mean the text is readable?
It means it clears one measurable bar. Line length, line height, letter spacing, the font itself and whether the text sits on a photograph all matter and none of them are in either number. A 4.5:1 pass in a thin 12px face is still hard work.
Feed it from
Palette Extractor
Pulls an N-colour palette out of an image and exports it as hex, CSS variables or an ASE swatch.
Average & Dominant Colour
Returns one representative colour for an image — mean, median or most frequent — as a colour asset.
Colour Blindness Simulator
Re-renders an image as protanopia, deuteranopia, tritanopia or greyscale vision would see it.
Colour Picker
Picks a colour on an OKLCH field, with a screen eyedropper or from an uploaded image, and copies it in any notation.
Next
These accept what this tool produces, so the result can go straight in.
Colour Blindness Simulator
Re-renders an image as protanopia, deuteranopia, tritanopia or greyscale vision would see it.
Tint & Shade Scale
Generates a 50–950 lightness scale from one colour with perceptually even steps, ready as design tokens.
Dark Mode Palette
Builds a 50–950 ramp from one colour and mirrors it into a dark one, so each token pair keeps its contrast.
Palette Generator
Builds a harmonious palette from a base colour using complementary, triadic and analogous rules.
Colour Format Converter
Converts a colour between HEX, RGB, HSL, HWB, LAB, LCH and OKLCH and names the nearest known colour.
Colour Picker
Picks a colour on an OKLCH field, with a screen eyedropper or from an uploaded image, and copies it in any notation.