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.
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
Related
- QR code design best practices: seven rules ranked, The seven design rules that decide whether a styled QR code scans, ranked by how often breaking them kills codes, with the number behind each rule.
- Inverted QR codes: the card pattern for dark designs, When a design demands a dark background, put a standard dark-on-light QR code on a light card rather than inverting it. How to size and style the card.
- Transparent background QR codes: the moving floor, A transparent QR code inherits whatever sits behind it as its background, so contrast must be re-checked per placement. When bg=t helps and when it bites.
- QR code inverted and unreadable, QR codes are defined dark-on-light. Inverted codes scan on some apps and fail on others, for no benefit. How to spot polarity problems and fix them fast.