Colored, gradient, dotted, logo-in-the-middle — the fancy codes look great, but half the internet warns they won't scan. So we ran the actual decode tests. Here's the data, and the three rules that keep a stylish code readable.
Short answer: yes, custom QR codes scan — if you respect three limits. We generated codes across dozens of colors, module shapes, and logo sizes, then ran each one back through a decoder to confirm it actually reads. Most "custom QR codes don't work" horror stories come from breaking one of these three rules.
A scanner sees a QR code as dark squares on a light background. The instant your color gets too light, that distinction collapses. We tested foreground colors against a white background and measured the WCAG contrast ratio of each:
| Foreground color | Contrast vs white | Scans? |
|---|---|---|
| Black / near-black | 17–21:1 | Yes |
Deep purple #7c3aed | 5.7:1 | Yes |
Crimson #e11d48 | 4.7:1 | Yes |
Emerald #059669 | 3.8:1 | Yes |
Sky blue #0ea5e9 | 2.8:1 | No |
Gold #ca8a04 | 2.9:1 | No |
The cliff sits right around 3:1. To leave margin for print, cheap camera sensors, and bad lighting, we recommend a contrast ratio of at least 4.5:1 — the same bar used for readable body text. That still leaves you every rich, saturated color: purples, indigos, magentas, deep teals, crimsons. It only rules out pastels and bright yellows on white.
Turning the little squares into dots looks modern, but it removes ink — the gaps between dots give a scanner less signal. In our tests, dotted codes at the default error-correction level failed outright. Bumped to the high (H) error-correction level, they scanned every time.
Two details matter: keep the dots full-size (touching their cell edges — shrinking them to 90% starved the decoder), and always keep the three finder squares in the corners solid. Those corners are how a scanner locates and orients the code; dot them and detection falls apart.
A QR code carries redundant data — that's how it survives a coffee stain. A center logo simply spends some of that redundancy. At the H error-correction level, a logo covering up to about 25% of the code's width reconstructed cleanly in every test. Past 30% it gets risky.
One gotcha we hit: a logo and dots on a very short link (a small code) can overwhelm the redundancy. The fix is to nudge the code to a slightly larger size so there are enough modules to recover — something a good generator should do for you automatically.
The vibestr studio bakes all three rules in — it checks contrast live and won't let you download a code that won't scan. Free, no signup.
Open the studio →A beautiful code is still a static code — it points at one URL forever. If that URL ever moves or the page comes down, the printed code is dead, no matter how good it looks. If you're printing on packaging, signage, or anything you can't reprint, use a dynamic code: it points at a redirect you can re-target anytime, and it keeps working for life.
SolidQR makes dynamic codes that keep redirecting forever — edit the destination or see your scans anytime, even if you cancel.
See SolidQR → Or design one free