Colour contrast matrix (WCAG 2.2 and APCA)
Check every pair in a palette of up to 16 colours for WCAG 2.2 contrast (AA, AAA, large text) and APCA lightness contrast in one grid.
A clear answer. Here’s how.
Each colour is converted to sRGB (a colour outside sRGB is first brought inside with the CSS Color 4 gamut-mapping algorithm) and rounded to 8 bits per channel, as a screen shows it. WCAG 2.2 relative luminance is L = 0.2126 R + 0.7152 G + 0.0722 B, where each channel c = value/255 becomes c/12.92 when c ≤ 0.04045 and ((c + 0.055)/1.055)^2.4 otherwise; the contrast ratio is (L1 + 0.05)/(L2 + 0.05) with L1 the lighter colour, from 1:1 to 21:1. AA needs 4.5:1 for normal text and 3:1 for large text (at least 18 pt, or 14 pt bold); AAA needs 7:1 and 4.5:1. Pass and fail use the unrounded ratio. The ratio is the same whichever colour is the text. APCA Lc (APCA-W3 0.0.98G-4g constants) depends on which colour is the text: it uses an exponent of 2.4 on each channel, soft-clamps near-black luminance below 0.022, and is positive for dark text on a light background and negative for light text on dark, with magnitudes up to about 108. APCA is the draft method proposed for WCAG 3 and is not a WCAG 2 requirement. Pairs are ranked by the WCAG ratio, then by the larger APCA magnitude. Neither method covers font weight, size or colour vision deficiency on its own.
How this is checked
5 reference checks passed These 5 cases were run when this page was built, on 20 October 2026, and all reproduce within the stated tolerance. The same cases are part of the automated tests that run on every change to Toolmoz. Engine version 1.
See the checks and where each expected answer comes from
Case 1
- Inputs
- Colours, one per line (an optional name first) White #ffffff Black #000000
- Expected, and what Toolmoz gave
- Contrast ratio, lines 1 and 2 expected 21, Toolmoz 21Pairs passing AAA normal text (7:1) expected 1, Toolmoz 1
- Where the expected answer comes from
- WCAG 2.2 definition: white has L = 1 and black L = 0, so (1 + 0.05) / (0 + 0.05) = 21
- Allowed difference
- ±1e-12
Case 2
- Inputs
- Colours, one per line (an optional name first) Grey #767676 White #ffffff
- Expected, and what Toolmoz gave
- Contrast ratio, lines 1 and 2 expected 4.542224959605253, Toolmoz 4.542224959605253Pairs passing AA normal text (4.5:1) expected 1, Toolmoz 1
- Where the expected answer comes from
- By hand with the WCAG 2.2 definition: 0x76 = 118, 118/255 = 0.462745, ((0.462745 + 0.055)/1.055)^2.4 = 0.181164, so 1.05 / 0.231164 = 4.5422
- Allowed difference
- ±1e-9
Case 3
- Inputs
- Colours, one per line (an optional name first) Grey #777777 White #ffffff
- Expected, and what Toolmoz gave
- Contrast ratio, lines 1 and 2 expected 4.478089453577214, Toolmoz 4.478089453577214Pairs passing AA normal text (4.5:1) expected 0, Toolmoz 0
- Where the expected answer comes from
- By hand: 0x77 = 119, 119/255 = 0.466667, ((0.466667 + 0.055)/1.055)^2.4 = 0.184475, so 1.05 / 0.234475 = 4.4781, which fails AA
- Allowed difference
- ±1e-9
Case 4
- Inputs
- Colours, one per line (an optional name first) Text #888 Background #fff
- Expected, and what Toolmoz gave
- APCA Lc, line 1 text on line 2 expected 63.056469930209424, Toolmoz 63.056469930209424APCA Lc, line 2 text on line 1 expected -68.54146436644962, Toolmoz -68.54146436644962
- Where the expected answer comes from
- apca-w3 package test values (APCA 0.0.98G-4g)
- Allowed difference
- ±1e-9
Case 5
- Inputs
- Colours, one per line (an optional name first) #123 #def
- Expected, and what Toolmoz gave
- APCA Lc, line 1 text on line 2 expected 91.66830811481631, Toolmoz 91.66830811481631APCA Lc, line 2 text on line 1 expected -93.06770049484275, Toolmoz -93.06770049484275
- Where the expected answer comes from
- apca-w3 package test values (APCA 0.0.98G-4g)
- Allowed difference
- ±1e-9
What this shows: the engine reproduces independently worked values for these cases. It does not prove every possible input is right. To test an answer you were given, see how to check a number; to see what is and is not checked across Toolmoz, see the accuracy ledger.
See a worked example
Worked example
A fixed demonstration, separate from the values you enter above.
- Colours, one per line (an optional name first)
Ink #1f2937 Paper #ffffff Brand blue #0072b2 Burnt orange #c24e00 Grey #767676 Sand #f5e9d3
- Table
- Pairs ranked by contrast
Example result
| Rank | Colour 1 | Colour 2 | WCAG ratio | AA normal (4.5:1) | AA large (3:1) | AAA normal (7:1) | APCA Lc, 1 as text on 2 | APCA Lc, 2 as text on 1 |
|---|---|---|---|---|---|---|---|---|
| 1 | Ink #1f2937 | Paper #ffffff | 14.68:1 | Pass | Pass | Pass | 101.5 | -104.3 |
| 2 | Ink #1f2937 | Sand #f5e9d3 | 12.22:1 | Pass | Pass | Pass | 89.1 | -90.8 |
| 3 | Paper #ffffff | Brand blue #0072b2 | 5.19:1 | Pass | Pass | Fail | -80.4 | 75.0 |
| 4 | Paper #ffffff | Burnt orange #c24e00 | 4.79:1 | Pass | Pass | Fail | -77.8 | 72.3 |
| 5 | Paper #ffffff | Grey #767676 | 4.54:1 | Pass | Pass | Fail | -77.0 | 71.6 |
Pass and fail use the unrounded ratio, so 4.499:1 fails AA. APCA Lc is from the draft APCA-W3 0.0.98G-4g method proposed for WCAG 3; it is not a WCAG 2 requirement. Positive Lc is dark text on a light background, negative is light on dark.