How scanners actually read contrast

A scanner isn't detecting "black" and "white" specifically — it's detecting a luminance difference between neighboring modules. Two colors can be completely different hues (say, a saturated blue and a saturated red) and still scan poorly if they happen to sit at a similar brightness level. This is why a QR code that looks visually "colorful and distinct" to a human eye can still be a bad scanner experience — human color perception and camera-sensor luminance detection aren't judging the image the same way.

The safest mental model: pick one clearly dark color and one clearly light color, in whatever hues you like, and keep them on opposite ends of the brightness scale.

Color combinations that work well

  • Dark, saturated module color (navy, forest green, deep purple, near-black) on a white or very light background — the most reliable option, and what most of the built-in presets default to.
  • Light or bright modules on a genuinely dark background (like the Spotify or Cyberpunk presets) — this works fine as long as the background is truly dark, not just medium-toned.
  • Gradients are safe as long as both gradient stops stay on the same side of the brightness scale relative to the background — a gradient that fades from dark purple to dark blue on a white background is fine; a gradient that fades from dark purple to pale yellow on a white background risks the pale end losing contrast.

Combinations to avoid

  • Light modules on a light or white background (pastel-on-white with insufficient contrast)
  • Mid-tone gray modules on a mid-tone gray or colored background
  • Very thin, low-coverage module shapes (like Hourglass or Star) combined with a subtle color difference — the shapes already reduce continuous dark area, so pair them with higher contrast, not lower

Don't forget the eyes

The three large squares in the corners — the "eyes" — are what most scanner apps use first to detect and orient a QR code before reading the data inside. If you recolor them, keep them at least as high-contrast as the modules, ideally identical or close to it. A beautiful gradient on the data modules paired with a barely-visible outer eye color is a common way a stylish code fails to even get detected in the first place.

Transparent backgrounds need extra care

A transparent background only maintains contrast if you know what it's being placed on top of. A code styled for a white product label will lose all contrast if that PNG later gets dropped onto a busy photo background. If you're not 100% sure of the final background, export with a solid color instead — it's the safer default.

Logos and color

The same contrast rule applies to your logo's plate color against the surrounding modules — see How to Add a Logo to a QR Code for the full logo-specific guidance, including error correction settings that make styled + logo'd codes more forgiving.

Pre-print checklist

  1. Zoom in on the eyes specifically — are they clearly visible against the background?
  2. Squint at the whole code, or view it in grayscale — does the pattern still read as clearly light/dark, or does it flatten into a uniform gray blob?
  3. Test-scan on at least two different phones, ideally different brands.
  4. If it's going to print, check it at the actual physical size it'll be printed at, not just zoomed in on a screen.