Dark Mode Done Right: Typography and Contrast Decisions
Dark mode isn't just about inverting colors. Learn the typography and contrast choices that make dark interfaces readable and professional.
Dark Mode Done Right: Typography and Contrast Decisions That Matter
Dark mode looks sleek. It reduces eye strain. It saves battery on OLED screens. But plenty of dark interfaces are painful to use because someone inverted the color palette and called it done. The difference between a dark mode that feels premium and one that feels half-baked comes down to typography choices and contrast ratios—the unglamorous fundamentals that actually determine whether people can read your product.
The Contrast Problem Nobody Talks About
Inverting your light theme's contrast doesn't work. A color that passes WCAG AA on a white background will fail spectacularly on dark gray. This trips up even experienced designers because contrast is relative to its surroundings.
Why Standard Ratios Fail in Dark Mode
WCAG AA requires a 4.5:1 contrast ratio for normal text. On light backgrounds, medium grays work fine. On dark backgrounds, they're invisible. Most teams discover this at QA stage and panic.
The reality: dark mode needs higher contrast than light mode for the same text size. A dark background demands lighter text, which creates more visual pop than the reverse direction. This isn't optional—it's physics.
Here's a practical test:
typescriptfunction checkContrast(foreground: string, background: string): number { const getLuminance = (hex: string) => { const rgb = parseInt(hex.slice(1), 16); const [r, g, b] = [ (rgb >> 16) & 255, (rgb >> 8) & 255, rgb & 255 ].map(x => x / 255); return 0.299 * r + 0.587 * g + 0.114 * b; }; const l1 = getLuminance(foreground); const l2 = getLuminance(background); const lighter = Math.max(l1, l2); const darker = Math.min(l1, l2); return (lighter + 0.05) / (darker + 0.05); } console.log(checkContrast('#ffffff', '#1a1a1a')); // 19.87:1 console.log(checkContrast('#666666', '#1a1a1a')); // 2.13:1 (fails)
That second ratio fails. Most gray text on dark backgrounds does.
Typography: Size and Weight Matter More in Dark
Dark mode amplifies every typographic decision. Thin weights that worked at 14px in light mode become frustrating in dark mode. The increased contrast makes text appear heavier than it is—optically, not technically.
Weight Adjustments
If your light theme uses 400-weight at body text size, consider 450–500 for dark mode. Not a full jump to 600, just enough to account for optical adjustment. At LavaPi, we've found that a simple weight offset prevents dark mode from feeling anemic or too bold.
Line Height and Spacing
Dark mode benefits from slightly higher line height. Light backgrounds allow tighter spacing because the white space reads as definition. Dark backgrounds need breathing room—increase line height by 0.15–0.2 from your light theme baseline.
typescriptconst typographyTokens = { light: { bodyText: { fontSize: '16px', fontWeight: 400, lineHeight: 1.5, color: '#1a1a1a' } }, dark: { bodyText: { fontSize: '16px', fontWeight: 450, lineHeight: 1.65, color: '#e8e8e8' } } };
Color Selection: Avoid Pure White
Pure white (#ffffff) against pure black creates excessive contrast that causes halation—that optical vibration where edges appear to glow. Use near-white instead: #e8e8e8 or #f0f0f0 for text, #1a1a1a or #0d0d0d for backgrounds.
Test your palette at actual reading distances and times. Contrast that passes automated checks can still strain eyes over extended use. If your team's squinting during the demo, adjust.
The Takeaway
Dark mode succeeds when you treat it as a separate design system, not an inversion. Adjust contrast ratios upward, increase weight slightly, add line height, and use near-white and near-black instead of extremes. These decisions sound small. They're what separate a dark mode people want to use from one they tolerate.
LavaPi Team
Digital Engineering Company