← Back to Course

Module 22

Dark Mode

Part B

Print vs Web

09

undefined

undefined

Part C

Science & Psychology

10

undefined

undefined

undefined
Vision Science

undefined

undefined
Halation Effect

undefined

undefined
OLED Benefits

undefined

Part D

Real-World Examples

11

Dark Mode Done Right

How top products implement dark mode.

Multiple themes

Light, dark, and high contrast

Principles Identified:
Choice Three themes plus custom colors
Accessibility High contrast option for low vision
Brand Accent colors remain vibrant

Dimmed colors

Syntax highlighting adjusted

Principles Identified:
Code-focused Syntax colors tuned for dark
Elevation Lighter surfaces for depth
Consistency Every page tested in dark

Dim & Lights Out

Two darkness levels

Principles Identified:
Options Dim (blue-gray) vs Lights Out (black)
OLED True black option for battery saving
Media Images pop against dark backgrounds

Part E

Common Failures

12

Dark Mode Mistakes

Common errors that hurt the dark mode experience.

Failure: Pure Black Background

Pure black #000

Harsh, causes halation

Fix: Use dark gray instead

Dark gray #111827

Comfortable contrast

Failure: Saturated Colors

Fully saturated

Vibrates on dark

Fix: Reduce saturation for dark backgrounds

Lighter, desaturated

Comfortable

Failure: Flash of Light Theme

Page loads light → then switches to dark

Jarring flash

Fix: Load theme preference before rendering

Theme applied before first paint

Smooth experience

Failure: Shadows for Elevation

Shadow invisible

Fix: Use lighter surfaces instead

Lighter surface

Part F

Visual Tests

13

Dark Mode Testing

Validate your dark mode implementation.

01

Low-Light Test

Tests: Comfort

View your site in a dark room for 5+ minutes. Is it comfortable? Does any element cause eye strain? Check for halation on text.

🌙

Test in actual low light

02

Contrast Audit

Tests: Accessibility

Check WCAG contrast ratios for all text. Dark mode often fails contrast checks. Aim for 4.5:1 for normal text, 3:1 for large text.

Normal text: 4.5:1 ✓

Large text: 3:1 ✓

Subtle text: 3:1+ needed

03

Image Audit

Tests: Visual consistency

Review every image in dark mode. Do bright images flash? Are logos visible? Do illustrations work on dark backgrounds?

☑ Photos adjusted

☑ Logos visible

☑ Icons adapt

04

Flash Prevention Test

Tests: Performance

Load page with dark mode preference set. Is there any flash of light theme? Check on slow connections.

Throttle to 3G

Reload with dark pref

No flash = pass

Part G

CSS Implementation

14

Dark Mode Implementation

Production-ready CSS for dark mode.

:root {
  --color-bg: #ffffff;
  --color-surface: #f9fafb;
  --color-text: #1f2937;
  --color-text-muted: #6b7280;
  --color-primary: #3b82f6;
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-bg: #111827;
    --color-surface: #1f2937;
    --color-text: #f9fafb;
    --color-text-muted: #9ca3af;
    --color-primary: #60a5fa;
  }
}
CSS Custom Properties via CSS
  • prefers-color-scheme - Detects system preference
  • Semantic names - Same tokens, different values
  • Lighter primary - Colors adjusted for dark
/* Data attribute approach */
[data-theme="dark"] {
  --color-bg: #111827;
  --color-text: #f9fafb;
}

/* JavaScript toggle */
function setTheme(theme) {
  document.documentElement.dataset.theme = theme;
  localStorage.setItem('theme', theme);
}

/* Load saved preference */
const theme = localStorage.getItem('theme') ||
  (matchMedia('(prefers-color-scheme: dark)').matches
    ? 'dark' : 'light');
setTheme(theme);
Manual Toggle via CSS
  • data-theme attribute - Easy to toggle in JS
  • localStorage - Persists user choice
  • Fallback to system - Respects OS if no choice
/* Reduce brightness slightly */
@media (prefers-color-scheme: dark) {
  img:not([src*=".svg"]) {
    filter: brightness(0.9) contrast(0.95);
  }
}

/* Dark mode logo swap */
.logo-light { display: block; }
.logo-dark { display: none; }

@media (prefers-color-scheme: dark) {
  .logo-light { display: none; }
  .logo-dark { display: block; }
}
Image Handling via CSS
  • filter - Subtle brightness reduction
  • Excludes SVG - SVGs adapt via currentColor
  • Logo swap - Different assets per theme
:root {
  --surface-1: #ffffff;
  --surface-2: #f9fafb;
  --surface-3: #f3f4f6;
}

@media (prefers-color-scheme: dark) {
  :root {
    --surface-1: #1f2937;
    --surface-2: #374151;
    --surface-3: #4b5563;
  }
}

.card {
  background: var(--surface-1);
}

.modal {
  background: var(--surface-2);
}
Elevation System via CSS
  • Surface levels - Increasing lightness
  • Light: shadows - Dark: lighter surfaces
  • Semantic usage - Modal higher than card

Part H

Self-Assessment

15

Self-Assessment

Test your understanding of dark mode implementation.

Q1

Why shouldn't you use pure black (#000) for dark mode backgrounds?

Click to reveal
Q2

How do you handle elevation in dark mode?

Click to reveal
Q3

What is FOUC and how do you prevent it?

Click to reveal