Design
Which QR code colour combinations actually scan
A scanner sees luminance, not hue, so brand colours that look bold on screen can be invisible to a camera. Here are the ratios that work and the ones that fail.
The brand guidelines say the accent colour is a warm orange, so the QR code on the packaging is orange on white. It looks confident on the mock-up and it is functionally a blank square to a phone camera: orange on white is a contrast ratio of about 2.8:1.
What the decoder actually sees
Before anything is decoded, the reader converts the camera frame to greyscale and binarises it — it picks a threshold and sorts every pixel into “dark module” or “light module”. Most implementations do this adaptively, in tiles, so uneven lighting across a large code does not sink it.
The consequence is blunt: the decoder never sees your colours, only how light or dark they are. Two colours that are unmistakably different to a human — red and green, orange and white — can land within a few percent of each other on the greyscale axis and become the same thing.
Luminance, not hue
The convenient way to measure this is the relative luminance contrast ratio used for text accessibility. It runs from 1:1 (identical) to 21:1 (black on white), weights green heavily and blue barely, and every design tool can compute it. It is not the metric in the standard — ISO/IEC 15415 grades printed two-dimensional symbols on reflectance difference, awarding its top grade at 70% symbol contrast or better — but it correlates well enough to make design decisions with, and you can check it before anything is printed.
Working thresholds:
- 10:1 and above — safe for public-facing print at any size.
- 7:1 to 10:1 — acceptable on a large, matte, well-lit code.
- 4:1 to 7:1 — risky; it will work on your phone and fail on plenty of others.
- Below 4:1 — broken. Do not ship it.
The combinations table
| Modules | Background | Ratio | Verdict |
|---|---|---|---|
Black #000000 | White | 21:1 | Safe |
Navy #0B1B3A | White | 17:1 | Safe |
Near-black #111827 | Off-white #F5F5F4 | 16:1 | Safe |
| Black | Yellow #FACC15 | 14:1 | Safe |
Royal blue #1E3A8A | White | 10:1 | Safe |
Slate #4B5563 | White | 7.6:1 | Safe |
| Black | Orange #F97316 | 7.5:1 | Safe |
Forest green #0B6623 | White | 7.1:1 | Safe |
Deep purple #6D28D9 | White | 7.1:1 | Safe |
Brick red #B91C1C | White | 6.5:1 | Risky |
Purple #6D28D9 | Lavender #EDE9FE | 6.0:1 | Risky |
Brand violet #7C3AED | White | 5.7:1 | Risky |
Teal #0F766E | White | 5.5:1 | Risky |
Red #DC2626 | White | 4.8:1 | Risky |
Mid grey #808080 | White | 3.9:1 | Broken |
Red #DC2626 | Yellow #FACC15 | 3.2:1 | Broken |
Cyan #00A3E0 | White | 2.9:1 | Broken |
Orange #F97316 | White | 2.8:1 | Broken |
Navy #1E3A8A | Slate #0F172A | 1.7:1 | Broken |
Yellow #FACC15 | White | 1.5:1 | Broken |
Two rows are worth staring at. Red on white is the combination people reach for most often and it sits at 4.8:1 — the marginal band, where success depends on the phone, the light and the print. And black on yellow at 14:1 is safer than half the “tasteful” dark-on-white pairings, which is not what most people would guess.
Why warm colours fail so hard
The luminance calculation weights the green channel at 0.7152, red at 0.2126 and blue at only 0.0722. Yellow and orange are mostly green plus red, so they compute as very light and sit right next to white on the greyscale axis. Yellow is the extreme case: at 1.5:1 against white it is genuinely invisible to a decoder.
Saturated red is the opposite case and catches people out for that reason. With
almost no green in it, #DC2626 computes as reasonably dark and reaches 4.8:1 —
which looks like a pass and is not one. It sits in the marginal band, where the
code works on a good phone in good light and fails often enough elsewhere to
ruin a print run.
There is a second, older reason to avoid red modules on anything that might meet dedicated hardware. Laser scanners — the kind at a supermarket till reading an EAN-13 — illuminate with a red diode around 660 nm. Red ink reflects red light, so a red symbol looks like blank background to that scanner. Phone cameras are broadband imagers and do not have this problem, but if a code might ever be read by fixed hardware, keep the modules dark and neutral.
Dark on light, and the inversion question
The specification’s model is dark modules on a light background, and readers optimise for it. Inverted codes — white on navy, white on black — do work with most modern phone software, which detects the polarity and flips it. “Most” is the problem. Some OEM camera apps on Android, some in-app scanners inside banking and ticketing apps, and essentially all laser-based readers will not.
Use inversion when you control the audience and the reader — an internal badge, a conference app, a screen where you can test. For a poster in a train station, stay dark on light. When inversion fails it fails silently, and the person just walks away.
Gradients, and where they break
A gradient across the dark modules can survive. The rule is that the lightest
point of the gradient must still clear the floor against the background, not
the average. A gradient from #1E3A8A to #7C3AED on white runs 10.4:1 down to
5.7:1, so it is a risky code masquerading as a safe one, and the failures will
cluster in whichever corner got the light end.
Gradients in the background are worse, because the adaptive threshold has to track a moving target underneath a fixed one. And any gradient that passes through the module colour at some point creates a region with no contrast at all. If a gradient is non-negotiable, keep both ends dark and put the whole range above 10:1.
Brand colours that survive
Three strategies, in order of how well they work:
- Use the brand’s darkest shade for the modules and white for the background. Most palettes contain a near-black or a deep navy that clears 10:1 comfortably. This is almost always the right answer.
- Put the brand colour behind black modules. Black on brand yellow, black on brand orange — both scan better than the brand colour on white, and the code still reads as yours from across the room.
- Keep the code black and brand the frame. A coloured card, a coloured panel, a logo underneath, with a plain black code and its full quiet zone in the middle. Boring, and it never fails.
What does not work is tinting the modules to a mid-tone of the brand colour so the code “sits better” in the layout. That is exactly the change that moves a code from 10:1 to 5:1. If the brand has to appear inside the square, a centred mark is the safer instrument than a tint — see putting a logo in a QR code without breaking it.
Transparent backgrounds and codes on photos
A transparent PNG has no background — it has whatever it is placed on. Drop it onto a dark hero image and you have inverted the code without meaning to; drop it onto a busy photograph and the module grid competes with the picture’s own dark regions. Either way the quiet zone is gone, because a photo does not contain four modules of blank margin.
If the code must sit on imagery, place a solid white plate behind it that extends at least four modules past every edge, and give the plate a slight shadow or border rather than fading it into the photo. The print size guide explains why that margin is structural rather than aesthetic.
The greyscale test
Before you approve any coloured code: convert the artwork to greyscale and look at it. If the pattern is still crisp, the decoder will see what you see. If it goes muddy, no error correction level will save it — redundancy repairs damaged modules, not modules the reader never resolved in the first place, which is one of the points in why your QR code is not scanning.
Then scan it. The generator previews colour changes live and exports SVG for print, so the greyscale check takes about ten seconds and catches the expensive mistake before it reaches a press.
Frequently asked
What contrast ratio does a QR code need?
Can a QR code have a gradient?
Do inverted QR codes with light modules on a dark background work?
Can a QR code be placed on top of a photo?
- colour
- contrast
- design
- branding
- scanning
Make the code this guide describes
The generator runs in your browser — add a logo, pick colours, tag the link with UTM parameters and download a PNG or SVG. No account, no watermark.
Keep reading
-
Troubleshooting
Why your QR code is not scanning
A QR code that fails to scan usually fails for one of eleven reasons, and this walks through each of them with the fix, from contrast to dead short links.
-
Design
Putting a logo in a QR code without breaking it
Error correction level H tolerates about 30 percent damage, which is not permission to cover 30 percent of the code. Here is the size that actually survives.
-
Printing
What size should a printed QR code be?
The distance-to-size rule that decides whether a printed QR code scans, the minimum millimetres per module, and the quiet zone people keep cropping off.