Why contrast is non-negotiable
A QR code decoder works by identifying dark modules against a light background. The decoder does not see colour - it sees relative brightness. A module is either dark (below a luminance threshold) or light (above it). If the difference in luminance between the module colour and the background colour is too small, the decoder cannot reliably distinguish them, and the code fails.
This is why a dark navy QR code on a medium-grey background can look visually distinct to a human - the colour difference is obvious - but still fail to scan: the brightness difference (luminance contrast) is insufficient.
What the contrast threshold actually is
The ISO/IEC 18004 standard (which governs QR codes) requires a minimum reflectance difference between the dark and light elements. In practical terms, this translates to a contrast ratio requirement similar to accessibility contrast standards.
For reliable scanning, a minimum contrast ratio of 3:1 between the module colour and background colour is recommended. Black (#000000) on white (#FFFFFF) gives a contrast ratio of 21:1 - the maximum possible.
The QR contrast checker on this site calculates the contrast ratio for any foreground and background hex colour combination and tells you whether it meets the threshold.
The inversion problem
A white QR code on a dark background is sometimes called an "inverted" QR code. Some decoders handle it fine. Others do not - particularly older scanning apps and many point-of-sale barcode readers.
If your design requires a dark background, the safest approach is to place the QR code on a white rectangle inset within the dark background, rather than inverting the module colours themselves. This preserves the standard dark-on-light orientation while still working within a dark layout.
Common contrast failures in production
Brand-coloured QR codes. A company uses its brand blue (#003087) as the module colour. On a light grey background, the code looks on-brand. But if that grey is #d0d0d0, the contrast ratio is around 4.5:1 - marginal. On a medium background (#b0b0b0), it may drop below 3:1 and start to fail on some scanners.
Gradient backgrounds. A QR code placed on a gradient background that transitions from light to dark will have adequate contrast on one half and fail on the other. The worst-performing region determines whether the code scans overall.
Coloured paper or card stock. A code printed in black ink on cream, buff, or coloured card stock will scan fine. A code printed with a coloured ink on any coloured card may not. The printer's rendering of your ink colour on the actual substrate matters - always test a physical proof.
Screen-to-print colour shifts. Colours that look high-contrast on screen sometimes shift significantly in print. A deep teal module colour that looks dark on a calibrated monitor can print significantly lighter on an uncoated stock. Request a colour proof before a production run.
Transparency and overlays. QR codes placed on top of images or textures inherit the contrast problems of whatever is behind them. A code placed on a photograph with variable light and dark regions will have inconsistent contrast across the code area.
The safe approach
If reliability matters more than aesthetics, use black modules on a white background. This is not a design failure - it is the standard for a reason.
If your design constraints require colour, follow these rules:
- The dark modules must be darker than the light background - never lighter.
- Calculate the contrast ratio using the QR contrast checker before approving the design.
- Test the actual printed output - not just the on-screen mockup.
- Keep the module colour in the dark range (luminance below 35%) and the background in the light range (luminance above 65%) for a comfortable margin.
Checking an existing printed QR code
If you have a printed QR code that is failing to scan and contrast is a suspected cause, photograph it under consistent lighting and upload the image. Note the background and module colours, then run them through the contrast checker. If the ratio is below 3:1, contrast is likely the issue.
Using the URL QR code generator, regenerate the code with black modules on a white background, reprint, and confirm it scans reliably before investigating other causes.