Design
QR code contrast — the 40% minimum, measured
A QR code needs a luminance difference of at least 40 percentage points between modules and background, with the modules darker. Luminance, not hue, is what decoders threshold on. Compute 0.2126R + 0.7152G + 0.0722B for each colour, subtract, and aim above 60 points for print and poor light.
The number and where it comes from
Before a decoder reads anything, it converts the image to greyscale and picks a threshold: everything darker is a module, everything lighter is background. For that threshold to exist reliably, the two sides need a luminance difference of at least 40 percentage points, with the modules on the dark side. Below 40 the threshold lands inside camera noise; above 60 the code survives dim light, glare and print.
Luminance weights the channels very unevenly:
L = 0.2126·R + 0.7152·G + 0.0722·B
Green dominates and blue barely counts — which is why a saturated blue reads as dark and a saturated yellow reads as nearly white, whatever they look like to a designer.
Pairs that pass and fail on white
Luminance below is computed with the formula above, expressed as a percentage of white. The difference column is what a decoder has to work with.
| Module colour | Hex | Luminance | Difference vs white | Verdict |
|---|---|---|---|---|
| Near-black slate | #0f172a |
9% | 91 | pass |
| Navy | #003366 |
17% | 83 | pass |
| Crimson | #e60023 |
20% | 80 | pass |
| Forest green | #228b22 |
43% | 57 | pass |
| Indigo | #6366f1 |
44% | 56 | pass |
| Mid grey | #808080 |
50% | 50 | pass, thin margin |
| Orange | #ff9900 |
64% | 36 | fail |
| Bright green | #25d366 |
65% | 35 | fail |
| Sky blue | #87ceeb |
76% | 24 | fail |
| Gold | #ffd700 |
82% | 18 | fail |
| Yellow | #ffff00 |
93% | 7 | fail |
Note how close the failures are to plausible brand palettes — the brand colour workflow shows how to darken a failing swatch without losing the hue.
This is not the WCAG ratio
WCAG's 4.5:1 rule measures a contrast ratio on linearised luminance and exists for reading text. QR decoding depends on a greyscale difference wide enough to threshold. The two metrics do not interchange: check text with WCAG and codes with the 40-point rule, and treat a pair that only passes one as failing.
How to measure a real pair
- Convert both colours with the formula, or desaturate the artwork in any image editor and read the two grey values.
- Subtract. Under 40: change a colour. 40–60: acceptable on screen, risky in print and dim rooms. Over 60: ship it.
- Run the finished file through the validator, which computes the actual contrast of the rendered pair and decodes it. If a code with adequate numbers still fails, the cause is usually elsewhere — see the colour troubleshooting page.
On-screen measurements are the best case. Ink spread, laminate glare, CMYK conversion and an angled camera each consume margin, so the 40-point floor is a floor, not a target. Remember polarity too: the difference must have the modules darker — an inverted pair fails differently even when the arithmetic passes.
FAQ
What is the minimum contrast for a QR code?
A luminance difference of at least 40 percentage points between modules and background, with modules darker. That is the working floor; above 60 points the code stays reliable in dim light, at an angle, and after printing.
Does hue matter for QR code contrast?
No. Decoders convert to greyscale first, so only luminance survives. A red and a green with the same luminance are identical to a scanner, which is also why QR codes are inherently safe for colour-blind users when the luminance rule is followed.
Is the WCAG 4.5:1 rule the same thing?
No. WCAG defines a contrast ratio for text legibility on linearised values, while QR decoding needs an absolute greyscale difference. Passing one does not guarantee the other, so codes should be checked against the 40-point rule directly.
Why does my high-contrast code still fail sometimes?
Screen numbers are the best case. Printing shifts colours, glossy laminate adds glare, and shadows compress the difference locally. Leave headroom by designing above 60 points, and decode a photograph of the final printed piece to confirm.
Try it — free, no signup
Related
- QR code design best practices — seven rules ranked — The seven design rules that decide whether a styled QR code scans, ranked by how often breaking them kills codes, with the number behind each rule.
- Brand colour QR codes that still scan — A three-step workflow for putting a brand colour on a QR code — measure the hex against white, darken the shade if it fails, keep the eyes darkest.
- Why light-on-dark QR codes fail — Decoders binarise expecting dark modules on a light background. Inverted support is inconsistent across scanners, so light-on-dark codes fail silently.
- QR codes on photos and textures — Photographic backgrounds destroy the local contrast QR decoding depends on. The worst-point rule, the backing card fix, and the dimming maths.