How the QR code contrast checker calculates the ratio
The QR code contrast checker compares the brightness of your foreground (dot) color and your background color and returns a contrast ratio, a dark-on-light check, and a plain verdict, updating live as you change either color. Use it to reject weak color pairs before you generate or print a code.
It runs entirely in your browser. Nothing about your colors or design is uploaded.
The formula
Each color is converted to a relative luminance, a single brightness value from 0 (black) to 1 (white), using the sRGB formula from WCAG 2.1 (unchanged in 2.2): each channel is normalized, gamma-expanded, then weighted 0.2126 R + 0.7152 G + 0.0722 B because the eye is far more sensitive to green than to blue.
The contrast ratio is then:
ratio = (L_lighter + 0.05) / (L_darker + 0.05)The result runs from 1:1 (two identical colors) to 21:1 (pure black on pure white) and is shown to two decimal places, for example 6.70 : 1.
The two checks it runs
| Check | Passes when | Badge |
|---|---|---|
| Dark on Light Rule | The foreground is darker (lower luminance) than the background | PASS, or FAIL if inverted |
| Minimum Contrast Rule (> 4:1) | Ratio is 4:1 or higher | PASS at 4:1+, WARN from 3:1 to 4:1, FAIL below 3:1 |
Those two combine into the headline verdict: a ratio of 10:1 or higher, dark-on-light, reads as Excellent; 4:1 or higher, dark-on-light, is Good; 3:1 to 4:1 is a Warning; anything inverted or below 3:1 is a Fail. The 4.5:1 mark matters too; below it, the Auto-Fix Contrast button appears.
Is 4:1 an official requirement?
No. There is no single contrast ratio that the QR standard requires. Print-quality verification uses physical reflectance measurements and standards such as ISO/IEC 15415, rather than this two-color screen calculation, and the WCAG thresholds this formula comes from (3:1, 4.5:1, 7:1) are written for people reading text and graphics, not for cameras decoding a grid.
The 4:1 line this checker draws is a practical screening threshold: it flags pairs for further review but does not predict a scan success rate. Treat it as a filter, not a certificate; see the QR code color and design guide for how to choose a branded palette, and always test a printed sample.
Example: checking a brand-blue QR code
You type #1D4ED8 into Foreground (Dots) Color and leave Background (Canvas) Color on #FFFFFF. The ratio reads 6.70 : 1. Dark on Light is PASS, Minimum Contrast is PASS, and the verdict is Good (Color contrast passes). No Auto-Fix button, because 6.70 is above 4.5. You press Start Generating with These Colors and the generator opens with both colors already set.
Now try a softer palette: #EF4444 dots on a #FEE2E2 pink background. The ratio drops to 3.08 : 1, the Minimum Contrast badge turns to WARN, the verdict becomes Warning (Low color contrast), and Auto-Fix Contrast appears. Clicking it darkens the red along the same hue, one step at a time, until the ratio clears 5:1; here it lands on about #BD1010 at 5.30 : 1, back to Good.
One more, to show the trap: white #FFFFFF dots on a navy #0F172A background scores a huge 17.85 : 1, but the verdict is Fail (Inverted QR code); the foreground is lighter than the background, so the Dark on Light check fails no matter how high the ratio climbs.
Reading the verdict
| Verdict | Means | Do next |
|---|---|---|
| Excellent | Dark-on-light, ratio 10:1 or higher | Generate a proof and test the actual lighting and stock |
| Good (Color contrast passes) | Dark-on-light, ratio 4:1 to 10:1 | Test the final size, surface, and intended scanners |
| Warning | Dark-on-light, ratio 3:1 to 4:1 | Use Auto-Fix or pick a darker foreground before printing |
| Fail (Inverted QR code) | Foreground is lighter than the background | Press Swap Colors, or put a normal dark code inside a light panel |
| Fail (Color screening) | Inverted and low contrast, or ratio below 3:1 | Start over with a dark color on a pale background |
The four Curated Accessible Presets are all safe starting points: Obsidian / White scores 21.00:1, Navy / Light Slate 17.06:1, Espresso / Cream 14.92:1, and Emerald / Mint 9.28:1. Auto-Fix Contrast only ever darkens the foreground (swapping first if the pair is inverted); it stops at the first shade that clears 5:1, which passes this color heuristic but does not establish scannability. For Excellent, keep going or choose black.
Who uses this
- Brand and marketing designers: check a brand color against white or a pale tint before committing it to a campaign's codes.
- Print pre-press: a fast sanity check on business cards, posters, and flyers, where a marginal ratio plus ink gain is a common failure.
- Packaging teams: codes land on kraft card, film, and colored stock; the background is rarely pure white, and this shows what that costs you.
- Accessibility reviewers: confirm a code and its "SCAN ME" caption clear a sensible contrast bar for low-vision users, not just for cameras.
- Anyone customizing colors in the generator: test here first, then hand the colors straight over with one button.
Contrast ratio vs. real-world scannability
The ratio is computed from two flat hex values on an idealized screen. A print run adds variables the math can't see: ink spreading into paper, a background that isn't as bright as its hex suggests, glare on a laminated surface, and industrial scanners that read under red light, where a red and a green of equal luminance can vanish into each other.
So a pass here means "not obviously broken", not "guaranteed to scan". For additional screening, run the finished code through the QR Code Validator, which stress-tests it against blur, low light, downscaling, and compression, and print a physical proof.
Tips, limits, and common mistakes
- A high ratio doesn't rescue an inverted code. White-on-dark can score 18:1 and still fail. If you need a dark design, put a normal dark-on-light code inside a light panel that includes the quiet zone.
- The checker compares two solid colors only. Gradients, photos, and textured fills behind the code introduce brightness values this tool never sees; the lightest part of a gradient foreground is what actually decides whether it scans.
- Hex is not ink. Screens are backlit; paper is not. Leave a buffer above the threshold (aim for Excellent, not a bare Good) before anything goes to a printer.
- Extend the background color into the quiet zone. The margin around the code has to be the same pale background, not the surrounding artwork, or the scanner loses the three finder squares.
- Don't trust hue difference. Two colors that look clearly different to you (a mid red and a mid green, say) can have almost the same luminance and merge into flat gray for a camera. The ratio is what matters, not how distinct the colors look.
- It checks color, not size or damage. Contrast is one input to scannability. Module size, quiet zone, and error correction are separate; the validator covers those.
Test the print, not just the pixels
Digital displays emit backlight that flatters every ratio. Before a physical run, print one copy on the real stock and scan it with an iPhone and an Android phone under normal room light; repeat this at the intended distance and lighting. A successful proof supports that tested configuration, not every future scan.