Detect and respond to system-level user preferences with CSS media queries
Implement automatic dark mode with prefers-color-scheme
Respect motion preferences using prefers-reduced-motion for accessibility
Adapt to contrast preferences with prefers-contrast
Handle transparency preferences with prefers-reduced-transparency
Create accessible, user-respecting designs that honor system settings
Combine preference queries with custom properties for maintainable themes
Introduction to Preference Queries
Modern CSS allows you to detect and respond to user system preferences automatically. These preference media queries enable your designs to respect accessibility settings, visual preferences, and motion sensitivities that users have configured at the operating system level. This creates more inclusive and comfortable experiences without requiring manual user configuration on your site.
Preference queries are essential for accessibility. Users with vestibular disorders may have enabled reduced motion settings. Users with light sensitivity may prefer dark themes. By respecting these preferences automatically, you demonstrate commitment to inclusive design and provide better experiences for users with diverse needs.
prefers-color-scheme - Dark Mode
The prefers-color-scheme media query detects whether a user has requested a light or dark color theme through their operating system settings. This is the foundation for implementing automatic dark mode support in your designs.
The prefers-reduced-motion media query detects if a user has requested to minimize the amount of animation or motion. This is critical for users with vestibular disorders, epilepsy, or those who simply find animations distracting or nauseating. Respecting this preference is not optional - it's an accessibility requirement.
/* Provide alternative feedback without motion */
.button {
background: blue;
transform: scale(1);
transition: transform 0.3s, background 0.2s;
}
.button:hover {
background: darkblue;
transform: scale(1.05);
}
@media (prefers-reduced-motion: reduce) {
.button {
transition: background 0.2s; /* Keep only color transition */
}
.button:hover {
transform: none; /* Remove scale animation */
background: darkblue; /* Keep color change for feedback */
}
}
prefers-contrast - High Contrast Mode
The prefers-contrast media query detects if a user has requested higher or lower contrast. High contrast mode helps users with low vision or color blindness distinguish interface elements more easily.
The prefers-reduced-transparency media query detects if a user has requested to reduce transparent or translucent effects. This can help users with visual processing issues or those who find transparency effects distracting.
Users may have multiple preferences enabled simultaneously. Your CSS should handle these combinations gracefully to provide the best possible experience.
/* Dark mode with reduced motion */
@media (prefers-color-scheme: dark) and (prefers-reduced-motion: reduce) {
.element {
background: var(--bg-dark);
animation: none;
transition: none;
}
}
/* High contrast with reduced transparency */
@media (prefers-contrast: high) and (prefers-reduced-transparency: reduce) {
.card {
background: #ffffff;
border: 3px solid #000000;
backdrop-filter: none;
}
}
/* Dark mode with high contrast */
@media (prefers-color-scheme: dark) and (prefers-contrast: high) {
:root {
--bg-primary: #000000;
--text-primary: #ffffff;
--border-color: #ffffff;
}
}
JavaScript Detection
While CSS handles styling automatically, you may need JavaScript to detect preferences for application logic or to provide manual override controls.
Testing these preferences during development is essential. Here's how to test on different platforms and in browsers.
Operating System Settings
/* macOS:
- Dark Mode: System Preferences → General → Appearance
- Reduce Motion: System Preferences → Accessibility → Display → Reduce motion
- Contrast: System Preferences → Accessibility → Display → Increase contrast
Windows:
- Dark Mode: Settings → Personalization → Colors → Choose your color
- Reduce Motion: Settings → Ease of Access → Display → Show animations
- Contrast: Settings → Ease of Access → High contrast
Linux (varies by distribution):
- Usually in System Settings → Appearance */
Browser DevTools
/* Chrome/Edge:
1. Open DevTools (F12)
2. Cmd/Ctrl + Shift + P → "Emulate CSS prefers-color-scheme"
3. Or: DevTools → Rendering tab → Emulate CSS media feature
Firefox:
1. Open DevTools (F12)
2. Inspector → Rules panel → Toggle color scheme icon
3. Or about:config → ui.systemUsesDarkTheme (0=light, 1=dark)
Safari:
1. Develop menu → Experimental Features → Dark Mode CSS Support
2. Elements tab → Styles panel → Force color scheme */