# Your site doesn&#39;t respect dark mode. Your visitors notice.

CSS media queries for prefers-color-scheme, prefers-reduced-motion, and prefers-contrast let your site adapt to user preferences. Most sites ignore them.

Author: J.A. Watte
Published: April 30, 2026
Source: https://jwatte.com/blog/blog-tool-user-preferences/

---

A visitor opens your site at 11 PM. Their phone is in dark mode. Their system fonts are set to high contrast. They have motion sensitivity enabled. Your site ignores all three preferences and blasts them with a white background, auto-playing animations, and tiny gray text on a slightly-less-gray background.

CSS has media queries for all of these preferences. They've been supported in every major browser since 2020. And yet most sites still serve a single visual experience regardless of what the user has configured on their device.

## The preference queries

**`prefers-color-scheme`** detects whether the user's operating system is set to light or dark mode. Values: `light` or `dark`.

```css
@media (prefers-color-scheme: dark) {
  body { background: #1a1a2e; color: #e0e0e0; }
  a { color: #7eb8da; }
}
```

82% of smartphone users have dark mode enabled, according to a 2023 Android Authority survey. On iOS, the adoption rate is similar. If you're not supporting dark mode, you're ignoring the majority preference of mobile users.

**`prefers-reduced-motion`** detects whether the user has enabled the "reduce motion" accessibility setting. This setting exists because vestibular disorders, migraines, and photosensitive epilepsy can be triggered by screen animations. About 5% of the general population has a vestibular disorder that makes motion sensitivity a medical concern, not a preference.

```css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
```

**`prefers-contrast`** detects whether the user has requested higher contrast. Values: `more`, `less`, `custom`, or `no-preference`. Windows High Contrast Mode and macOS Increase Contrast both trigger this.

```css
@media (prefers-contrast: more) {
  body { background: #000; color: #fff; }
  a { color: #ffff00; text-decoration: underline; }
  button { border: 2px solid #fff; }
}
```

**`forced-colors`** detects when the user is in Windows High Contrast Mode, which completely overrides site colors. You can't fight it (the browser enforces system colors), but you can adapt layout and borders to look correct under forced colors.

## The dark mode FOUC problem

The most visible implementation mistake is FOUC (Flash of Unstyled Content) during dark mode. If your dark theme is applied via JavaScript after page load, users see a white flash before the dark styles kick in. On a phone in a dark room, that flash is physically uncomfortable.

The fix is to apply the theme before the page renders. Two approaches:

**CSS-only (recommended):** Use `prefers-color-scheme` in your stylesheet. The browser applies it before first paint because CSS is render-blocking by design.

**CSS custom properties with a `<meta>` tag:** Set `<meta name="color-scheme" content="light dark">` in the `<head>`. This tells the browser to use the system's default styling (including dark scrollbars, form controls, and backgrounds) before your CSS loads.

```html
<meta name="color-scheme" content="light dark">
```

This single tag eliminates the white flash on pages where your CSS hasn't loaded yet. It's the lowest-effort improvement you can make for dark mode support.

## What a proper implementation looks like

A good user preference implementation uses CSS custom properties (variables) with media queries:

```css
:root {
  --bg: #ffffff;
  --text: #1a1a1a;
  --link: #0066cc;
  --border: #e0e0e0;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1a1a2e;
    --text: #e0e0e0;
    --link: #7eb8da;
    --border: #333355;
  }
}

body { background: var(--bg); color: var(--text); }
a { color: var(--link); }
```

This approach makes every color in your design responsive to the user's preference without duplicating your entire stylesheet. Add a manual toggle (stored in `localStorage`) for users who want to override the system default, and you've covered the full use case.

## Accessibility isn't optional

`prefers-reduced-motion` and `prefers-contrast` aren't nice-to-have features. WCAG 2.1 Success Criterion 2.3.3 ("Animation from Interactions") recommends respecting the reduced-motion preference. The European Accessibility Act (effective June 2025) and ADA compliance expectations in the US increasingly treat motion sensitivity accommodations as requirements, not suggestions.

The implementation cost is minimal. A single `@media (prefers-reduced-motion: reduce)` block that disables animations and transitions takes 5 lines of CSS. The risk of not implementing it: an accessibility lawsuit, or more practically, users with motion sensitivity closing your tab and never returning.

## What the tool checks

The [User Preferences Audit](/tools/prefers-color-scheme-audit/) scans your page for:

- `prefers-color-scheme` media queries in stylesheets and inline styles
- `prefers-reduced-motion` handling for animations and transitions
- `prefers-contrast` support
- `<meta name="color-scheme">` tag in the `<head>`
- Dark mode FOUC risk (JavaScript-applied themes without CSS fallback)
- `forced-colors` media query presence
- Color contrast ratios in both light and dark modes

The tool generates a remediation prompt with CSS snippets for each missing preference, tailored to your existing design tokens.

If you're building sites that need to work for every visitor, not just the ones whose settings happen to match your defaults, *The $20 Dollar Agency* ($9.99 on Kindle) covers the accessibility and usability foundations that make lean sites feel professional.

## Fact-check notes and sources

- Dark mode adoption (82%+ on Android): [Android Authority, 2023 survey](https://www.androidauthority.com/dark-mode-poll-results-3330498/)
- Vestibular disorder prevalence (~5%): [National Institute on Deafness, Balance Disorders](https://www.nidcd.nih.gov/health/balance-disorders)
- prefers-color-scheme browser support: [Can I Use prefers-color-scheme](https://caniuse.com/prefers-color-scheme) (all major since 2020)
- WCAG 2.1 SC 2.3.3: [W3C, Animation from Interactions](https://www.w3.org/WAI/WCAG21/Understanding/animation-from-interactions.html)
- color-scheme meta tag: [MDN, color-scheme](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name#color-scheme)
- European Accessibility Act: [European Commission, EAA directive](https://ec.europa.eu/social/main.jsp?catId=1202)

## Related reading

- [Non-composited animation audit](/blog/blog-tool-non-composited-animation/) — performance-safe animations
- [Critical CSS audit](/blog/blog-tool-critical-css/) — render-blocking style optimization
- [CrUX field data](/blog/blog-tool-crux-field-data/) — real-user experience metrics
- [CSP allowlist audit](/blog/blog-tool-csp-allowlist/) — security headers that affect style loading
- [Font loading strategy](/blog/blog-tool-font-loading-strategy/) — font-display and swap patterns

*This post is informational, not accessibility-consulting advice. Tool mentions are descriptive. No affiliation with browser vendors is implied.*

---

Canonical HTML: https://jwatte.com/blog/blog-tool-user-preferences/
RSS: https://jwatte.com/feed.xml
JSON Feed: https://jwatte.com/feed.json
Hero image: https://jwatte.com/images/blog-tool-user-preferences.webp
