# Gradient QR codes that still scan

> A gradient QR code scans reliably when every stop of the gradient (especially the lightest) keeps at least a 40 percentage-point luminance difference against the background. Apply the gradient to the modules only, keep the background solid and light, and decode the finished render to prove the weakest point still reads.

Source: https://useqr.app/docs/design/gradient-qr-codes · Last reviewed 2026-08-21 · UseQR is free forever, no signup.

---

## The rule: judge the lightest stop, not the average

A decoder does not see a gradient; it sees each module at whatever luminance the
gradient gives it locally. So a gradient passes only if **both ends** (and every stop
between) satisfy the [40-point contrast rule](/docs/design/qr-code-contrast-ratio-minimum)
against the background. The average being dark enough means nothing if one corner of
the code fades to a pastel.

Worked example on white, using L = 0.2126R + 0.7152G + 0.0722B:

| Stop | Hex | Luminance | Difference vs white | Verdict |
|---|---|---|---|---|
| Deep indigo | `#312e81` | 21% | 79 | pass |
| Violet | `#7c3aed` | 33% | 67 | pass |
| Light violet | `#a78bfa` | 60% | 40 | on the floor, reject |

An indigo-to-violet gradient (`#312e81 → #7c3aed`) is safe everywhere. Extend it to the
light violet and the code's pale end sits exactly on the minimum with zero headroom for
print or dim light, the kind of margin that produces
[codes that fail only sometimes](/docs/troubleshooting/qr-code-colors-not-scanning).

## Linear vs radial

**Linear** gradients spread the light end across one edge or corner of the code. At 45°
one corner, including one [finder pattern](/glossary/finder-pattern): gets the
lightest ink, so the lightest stop must pass with room to spare.

**Radial** gradients are riskier than they look: with a dark centre fading outward, the
*corners* are the lightest region, and all three finder patterns live in corners. If
the eyes are the weakest-contrast part of the symbol, detection fails before decoding
starts. Two fixes: keep the radial range narrow (both stops well past 40 points), or
paint the eyes with a solid dark colour so they opt out of the gradient entirely.

Two further rules regardless of direction: the gradient belongs on the **modules
only**: a gradient background gives the decoder no single threshold to find, the same
failure as [photographic backgrounds](/docs/design/qr-codes-on-photos-and-textures),
and both stops should share a similar hue so the code reads as one object rather than
patchwork.

## Doing it in UseQR

Foreground gradients are a URL parameter, so a gradient style is shareable and
reproducible:

```
fg=l45~312e81~7c3aed    linear, 45° rotation, two stops
fg=r~312e81~7c3aed      radial, centre to edge
```

Add `eyefg=312e81` (and `ballfg=`) to hold the eyes at the darkest stop, the cheap
insurance described above. Try it directly:
[a linear gradient code](/url?fg=l45~312e81~7c3aed&eyefg=312e81).

Then prove it: the [validator](/validate) rasterises the styled code and reads it back
with a real decoder, which is the only test that accounts for the gradient's weakest
point, the eye colours and the styling together. UseQR runs the same decode-verify
check before every download, but re-verify after any recolouring in a design tool.

## FAQ

### Do gradient QR codes scan?

Yes, when every stop of the gradient keeps at least a 40 percentage-point luminance
difference against the background. Codes fail when the light end of the gradient drifts
too close to the background, the average colour being dark enough is not sufficient.

### Should the gradient be on the modules or the background?

The modules only. A gradient background varies the luminance the decoder must threshold
against, which can make different regions of the code binarise inconsistently. Keep the
background solid and light: white is the safe default.

### Are radial gradients worse than linear ones?

Slightly, in one specific way: a dark-centre radial gradient makes the corners the
lightest region, and the three finder patterns sit in corners. Keeping the eyes a solid
dark colour removes that risk and costs nothing visually.

### How do I test a gradient QR code?

Decode the final rendered file with a validator, not just your own phone. A real
decoder pass proves the lightest stop, the eye colours and the module styling work
together, and testing a printed sample under dim light confirms the headroom survives
production.

## Try it

- https://useqr.app/url
- https://useqr.app/validate
