Skip to content
UseQR
ESC

↑↓ MOVE↵ OPEN48 PLACES

Design

QR codes on a dark-mode website

Dark mode flips your page background, and a transparent-background QR code silently becomes light-on-dark — which many scanners refuse. Give every embedded code its own explicit light card, dark modules on a white rectangle that ignores the theme. If you swap colours per theme, swap both foreground and background so polarity stays dark-on-light.

View as MarkdownPaste this page into any AI assistant — it is plain, portable Markdown.

The failure, precisely

A QR code exported with a transparent background borrows whatever sits behind it. On a light page that is fine. When prefers-color-scheme: dark swaps the page background to near-black, the same dark modules now sit on a dark ground — and if the modules were themed to a light colour, the code has become light-on-dark: inverted polarity. Support for inverted codes is patchy across scanner implementations — the details are in inverted QR codes — so the practical symptom is a code that works for some visitors and silently fails for others, exactly the pattern described in inverted and unreadable. Nobody tests this, because developers preview in one theme.

Fix 1: an explicit light card

The robust answer is to make the code's background its own, not the page's:

.qr-card {
  background: #fff;          /* literal white — not a theme token */
  padding: 12%;              /* the quiet zone, scaling with the card */
  display: inline-block;
  border-radius: 8px;
}

The one rule that matters: the card's background must not be a variable that flips with the theme. A white card on a dark page looks deliberate, gives the decoder its quiet zone, and works in every theme without further thought. Why transparency is a liability in general — email clients, PDFs, unknown embedding contexts — is covered in transparent background QR codes, and the padding arithmetic in aspect and padding.

Fix 2: mind the currentColor trap

Inline SVG codes often inherit text colour:

<!-- Trap: modules follow the theme's text colour -->
<svg class="qr"><path fill="currentColor" d="…"/></svg>

Dark themes set text to near-white, so the modules turn white — light-on-dark again, or white-on-white inside a light card. Give modules a literal fill (fill="#111") and the SVG an explicit background rect. currentColor is a fine default for icons and a trap for QR codes.

Fix 3: theme the pair, never the polarity

If the design insists the code participate in the theme, swap foreground and background together, keeping dark modules on a light ground in both states:

.qr-card { background: #fff; }
.qr-card svg path { fill: #111; }

@media (prefers-color-scheme: dark) {
  .qr-card { background: #ececec; }  /* softened, still light */
  .qr-card svg path { fill: #111; }  /* polarity unchanged */
}

An off-white card reads gentler on a dark page and still clears the 40% luminance difference with room to spare. What must never happen is the naive swap — light modules on the dark page — which is the inverted failure with extra steps.

Remember who scans it

A code on a website is scanned by a phone pointed at a monitor (the mechanics have their own quirks) or decoded from a screenshot — and the screenshot preserves whichever theme the visitor had. Test both themes with a real phone, and run a screenshot of each through the validator; it takes two minutes and catches the failure the preview never shows.

FAQ

Why does my QR code not scan in dark mode?

Almost certainly polarity: a transparent or theme-coloured code has become light modules on a dark background, and many scanners only reliably decode dark-on-light. Put the code on an explicit white card that does not change with the theme.

Should a QR code invert its colours in dark mode?

No. Keep dark modules on a light background in both themes. If the pure white card feels harsh on a dark page, soften it to a light grey — the polarity and the 40% luminance difference are what must survive the theme switch.

Is currentColor safe for SVG QR codes?

No. currentColor follows the theme's text colour, so dark themes silently turn the modules light. Give the module paths a literal dark fill and the SVG an explicit light background rectangle.

How do I test a QR code in both themes?

Toggle prefers-color-scheme in the browser's dev tools, scan the rendered page from a phone in each theme, and decode screenshots of both with a QR validator. The failure only appears in the theme you did not design in.

Try it — free, no signup