Using CSS prefers-contrast for High-Contrast Needs
The CSS prefers-contrast media query detects whether a
user has requested an interface with heightened or diminished contrast
through their operating system settings. This article explains how the
media feature functions, details its available values, and demonstrates
practical CSS techniques to adapt colors, borders, and typography to
meet high-contrast accessibility requirements.
Understanding
prefers-contrast
Part of the CSS Media Queries Level 5 specification,
prefers-contrast queries the user's system preferences to
adjust the visual presentation of a website automatically. This is
critical for users with low vision, color blindness, or situational
impairments (such as viewing a screen in direct sunlight).
The media feature supports four primary values:
no-preference: The user has not expressed a preference. This serves as the default state.more: The user prefers a higher level of contrast between elements and backgrounds.less: The user prefers a lower level of contrast, often to reduce eye strain or migraine triggers.custom: The user has enabled a specific, restricted palette (such as Windows High Contrast Mode) where forced colors are applied.
Adapting Styles for High-Contrast Needs
When users request higher contrast
(prefers-contrast: more), subtle design patterns—like faint
borders, soft shadows, low-contrast text, or pastel backgrounds—can
become unreadable. Developers use this query to deliver a sharper,
clearer interface.
1. Boosting Text and Background Contrast
Websites often use off-blacks, grays, and muted tones for secondary text. In high-contrast mode, these should be adjusted to achieve maximum contrast ratios.
/* Default styles */
body {
background-color: #f9f9f9;
color: #555555;
}
/* High-contrast adaptation */
@media (prefers-contrast: more) {
body {
background-color: #ffffff;
color: #000000;
}
}2. Enhancing Interactive Elements and Borders
Modern UI design frequently relies on subtle drop shadows
(box-shadow) to differentiate cards, inputs, and buttons.
For users needing high contrast, distinct solid borders are much more
perceptible.
.card {
background: #ffffff;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
@media (prefers-contrast: more) {
.card {
box-shadow: none;
border: 2px solid #000000;
}
}3. Strengthening Focus States and Outlines
Standard focus rings can blend into complex backgrounds. Enhancing
the focus outline when prefers-contrast: more is active
ensures users navigating via keyboard can easily track their
position.
button:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}
@media (prefers-contrast: more) {
button:focus-visible {
outline: 3px solid #000000;
outline-offset: 3px;
}
}4. Removing Decorative Noise
Subtle gradients, background patterns, and semi-transparent overlays can reduce readability. Inside the high-contrast query, flatten these elements into solid, opaque colors to keep the foreground text legible.
.hero-banner {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #ffffff;
}
@media (prefers-contrast: more) {
.hero-banner {
background: #00008b; /* Solid dark blue */
color: #ffffff;
}
}prefers-contrast
vs. forced-colors
It is important to differentiate prefers-contrast from
the forced-colors media query. While
forced-colors signals that the operating system has
restricted the palette to a limited system set (overriding author colors
automatically), prefers-contrast: more allows the developer
to intentionally refine their own design palette to ensure compliance,
maintain visual hierarchy, and provide an accessible experience tailored
to the user's needs.