Choose QR colors that scan clearly
Phones don't see your brand colors. They see light and dark. A colored code scans when its dark parts are clearly darker than the background everywhere, including the weakest point of a gradient.
What a scanner actually measures
A QR decoder turns the camera image into a grid of light and dark modules. To do that it picks a threshold, usually adapting across the image, and calls everything darker than it "dark". Hue is mostly thrown away. Two colors that look completely different to you, like a saturated orange and a mid grey, can sit at almost the same brightness, and a decoder will struggle to split them from a white background.
So the useful question is: how far apart are the foreground and background in brightness? The most practical measure we have is theWCAG contrast ratio, which is built onrelative luminance.
Luminance and the contrast ratio
Relative luminance converts an sRGB color into perceived brightness from 0 (black) to 1 (white). Each channel is first linearised:
c = channel ÷ 255
c_lin = c ≤ 0.04045 ? c ÷ 12.92 : ((c + 0.055) ÷ 1.055) ^ 2.4
L = 0.2126 × R_lin + 0.7152 × G_lin + 0.0722 × B_linGreen dominates, blue barely counts. The contrast ratio between the lighter (L1) and darker (L2) color is then:
ratio = (L1 + 0.05) ÷ (L2 + 0.05)It runs from 1:1 (identical) to 21:1 (black on white). WCAG was written for people reading text, not for camera sensors, so treat the number as a screening test rather than a guarantee. In practice it tracks scanning well. Our generator passes 4.5:1 and above, warns between 3:1 and 4.5:1, and fails anything lower.
Safe and risky color pairs
These ratios are computed with the formula above, the same code our generator and contrast checker use.
| Colors | Swatch | Ratio | Verdict | Note |
|---|---|---|---|---|
Black on white#000000 on #ffffff | 21.00:1 | Safe | The reference. Use it when nothing else matters. | |
Navy on white#12172b on #ffffff | 17.75:1 | Safe | Reads as black at a glance, softer in a layout. | |
Espresso on cream#3a2418 on #fbf5ea | 13.39:1 | Safe | Warm stock still leaves plenty of contrast. | |
Dark navy on pale blue#0b1f5c on #e7eeff | 13.24:1 | Safe | A tinted background costs little if the ink is dark. | |
Sage green on ivory#2e4a3c on #fffdf6 | 9.55:1 | Safe | A muted color that is still well within range. | |
Ultramarine on white#2b3cf0 on #ffffff | 6.98:1 | Safe | Bright but dark enough. | |
Crimson on white#c0122d on #ffffff | 6.24:1 | Safe | Fine on paper. Test under warm or red lighting. | |
Magenta on white#e0217c on #ffffff | 4.49:1 | Test carefully | Just under 4.5:1. Usually scans; test it. | |
Mid grey on white#888888 on #ffffff | 3.54:1 | Test carefully | A common tint-of-black mistake. | |
Orange on white#ff6a00 on #ffffff | 2.87:1 | Risky | Looks vivid, but is light in luminance. | |
Cyan on white#00b3e6 on #ffffff | 2.44:1 | Risky | Process cyan alone is too light. | |
Gold ink on white#c9a227 on #ffffff | 2.42:1 | Risky | Flat gold is pale; foil behaves differently again. | |
Yellow on white#f2c200 on #ffffff | 1.68:1 | Risky | Close to invisible to many scanners. |
The pattern: dark, slightly muted inks on light stock are safe. Bright "brand" colors, especially yellows, oranges, cyans and light greens, carry less luminance than they appear to. If your brand color fails, use a darker shade of it for the modules and keep the bright version for the frame or the logo.
Two codes, side by side
Both encode the same link to this page. Try scanning each from your screen and then from a print.
Dark on light matters
QR codes were designed as dark modules on a light background, and that's what every scanner looks for first. A light-on-dark code, often called inverted, is allowed by the current edition of ISO/IEC 18004, and recent iPhone and Android camera apps generally read it. But some decoders only try the inverted image as a fallback, at extra cost, and some older or third-party apps don't try it at all. If a code has to work for everyone, keep it dark on light. If your design is dark, place the code on a light panel or plate.
Gradients: measure the weakest point
A gradient is only as strong as its lightest part. In a simple two-stop gradient that's usually one of the ends; with three or more stops, the lightest color can sit anywhere, including the middle of the code. Check every stop against the background. Our generator samples along the whole gradient and reports the weakest value, not the average.
Gradients that run from dark to darker, like ultramarine to deep magenta, are safe: both ends here are above 6.5:1 against white. Gradients that fade towards the background color are not, because part of the code effectively disappears. Watch the finder patterns, the three large squares in the corners. If a gradient makes one of them weak, the scanner may not locate the code at all.
Separate eye colors work the same way. Each eye color needs its own contrast against the background.
Transparent backgrounds
A transparent PNG or SVG has no background of its own; it takes whatever it's placed on. That's useful for putting a code on colored packaging, but the contrast now depends on the surface, not the file. Our scan check measures against white when the background is transparent and warns you to check the real surface. Two rules:
- The surface behind the code, including the four-module quiet zone, must be plain and light.
- Avoid semi-transparent modules. A 60% opacity navy over a photo isn't navy any more; its contrast changes across the image.
Print: inks, foil and finishes
Use solid black for small codes
Rich black (black built from cyan, magenta, yellow and black inks) looks deeper, but if the plates are slightly out of register, colored fringes appear along every module edge. On a small code that can smear module boundaries. Ask for 100% K, a single ink, for codes on business cards and labels.
Metallic and foil
Foil and metallic inks don't have a fixed brightness. Depending on the angle and the light source, the same foil can look nearly white (a reflection) or nearly black (reflecting a dark room). That makes foil modules unreliable. If you want foil, put it on the frame or the logo and print the modules in a flat ink on a matte area. If the whole code must be foil, test it under the real lighting at several angles.
Gloss, laminate and spot UV
Glossy surfaces reflect light sources straight into the camera, washing out part of the code. Matte laminate is kinder. Avoid spot UV over the modules, and avoid putting a glossy code where a ceiling light sits directly above it.
Colored stock
A kraft or colored paper lowers the background's luminance, which lowers contrast with any ink. Dark brown ink on kraft is often fine; mid-tone inks on kraft often aren't. Paste your stock's color into the contrast checker as the background.
A quick checklist
- Weakest contrast of 4.5:1 or more, including every gradient stop and eye color.
- Dark modules on a light background, unless you know your audience's scanners handle inverted codes.
- A plain, light quiet zone on the final surface.
- No foil, gloss or spot UV on the modules themselves.
- A printed proof scanned under the real lighting. See how to test a QR code.
Ready to try colors? The colored QR code generator shows the weakest contrast live as you edit.