Dark Mode Accessibility Checklist
For: Designers, design system maintainers, frontend developers
Dark mode that "looks right" in Figma can fail accessibility audits because contrast ratios behave differently against dark backgrounds and pure-white text on pure-black actually causes eye strain (halation). This checklist covers what to check separately for dark mode — not just "the same items as light mode."
References: WCAG 2.2 (extended for color schemes) · iOS Human Interface Guidelines — Dark Mode · Material Design — Dark Theme
Want to audit color contrast against this checklist on real screens — instantly, from your phone?
Use AccessAudit AI — runs offline, captures photo evidence per item, exports a sharable PDF.
Color Strategy
Avoid pure white (#FFFFFF) text on pure black (#000000) — causes halation. Use #E0E0E0 on #121212 or similar.
Brand colors re-tuned for dark mode (a color that pops on white often muddies on dark)
Saturation reduced ~10-20% for dark mode (high saturation strains eyes against dark)
Use elevation tokens (slightly lighter surfaces) instead of shadows (which don't show on dark)
Contrast (re-verify, don't assume)
Body text ≥4.5:1 against dark background (RECALCULATE — often fails when light-mode passed)
Large text ≥3:1 against dark background
WCAG 1.4.3
UI controls ≥3:1 against dark background
WCAG 1.4.11
Focus indicators visible against the dark surface
System Respect
CSS prefers-color-scheme media query honored, no JS-only switch
Manual override (toggle in app) persists across sessions
No mixed-mode flicker on page load (CSS variable approach loaded synchronously)
Imagery & Icons
Icons swap to lighter variants in dark mode (or use mask-based monochrome icons)
Photos with white backgrounds stand out unpleasantly — apply slight overlay or border
Inline SVGs use currentColor so they inherit theme color automatically
PNG/JPG images that include text still readable when the surrounding theme inverts
Run this on your phone
Point your iPhone camera at any color pair to see WCAG contrast ratio + pass/fail in real time. 100% on-device.