How Safari Honors Accessibility CSS Media Queries
This article provides a comprehensive overview of how the Safari web
browser translates operating system accessibility configurations into
actionable CSS media queries. Specifically, it explains how Apple’s
WebKit engine listens to macOS, iOS, and iPadOS system preferences to
trigger the prefers-reduced-motion and
prefers-contrast media features, allowing web developers to
deliver tailored, accessible user experiences automatically.
The Bridge Between OS Settings and WebKit
Safari relies on its underlying layout engine, WebKit, to communicate directly with the host operating system. When a user adjusts their accessibility preferences in macOS, iOS, or iPadOS, the operating system broadcasts this state change. Safari intercepts these system-level flags and maps them directly to standard W3C CSS Media Queries. This happens in real-time, meaning open web pages will immediately adapt to the new settings without requiring a page reload.
How Safari Handles
prefers-reduced-motion
The prefers-reduced-motion media query is used to detect
if the user has requested the system minimize the amount of
non-essential animation or motion it uses. This is critical for users
with vestibular motion disorders.
System Configuration:
- macOS: Enabled via System Settings > Accessibility > Display > Reduce motion.
- iOS/iPadOS: Enabled via Settings > Accessibility > Motion > Reduce Motion.
Safari’s Implementation: By default, if the user has
not altered their settings, Safari evaluates the media query value as
no-preference. Once the user toggles the "Reduce Motion"
switch on in their system settings, Safari switches the active value to
reduce.
Web developers can hook into this behavior using CSS:
.animation-element {
transition: transform 0.5s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
.animation-element {
transition: none;
}
}When Safari detects the system setting is active, it applies the CSS
rules inside the @media (prefers-reduced-motion: reduce)
block, effectively stripping out the transition.
How Safari Handles
prefers-contrast
The prefers-contrast media query is used to detect if
the user has requested the system increase or decrease the amount of
contrast between adjacent colors. This assists users with low vision or
color blindness.
System Configuration:
- macOS: Enabled via System Settings > Accessibility > Display > Increase contrast.
- iOS/iPadOS: Enabled via Settings > Accessibility > Display & Text Size > Increase Contrast.
Safari’s Implementation: The CSS specification
allows for several values: no-preference,
more, less, and custom. Because
Apple's operating systems only provide a binary toggle to "Increase
Contrast", Safari specifically maps this setting to two values:
no-preference: The default state when "Increase Contrast" is turned off.more: The active state when "Increase Contrast" is turned on.
Safari does not natively trigger the less value from
standard system accessibility toggles, as there is no "Decrease
Contrast" setting in macOS or iOS that maps to WebKit for this purpose
(the "Reduce White Point" setting on iOS does not trigger this
query).
Developers use this in Safari to harden UI elements and improve text legibility:
.text-box {
color: #666666;
border: 1px solid transparent;
}
@media (prefers-contrast: more) {
.text-box {
color: #000000;
border: 2px solid #000000;
}
}Detecting Changes via JavaScript in Safari
In addition to CSS, Safari exposes these accessibility states to the
Document Object Model (DOM) via the window.matchMedia()
API. This is necessary when animations or contrast levels are controlled
by JavaScript (such as HTML5 Canvas animations or WebGL) rather than
CSS.
Safari allows developers to check the current state and listen for real-time changes if a user toggles their settings while browsing:
// Check for Reduced Motion in Safari
const motionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
function handleMotionChange(event) {
if (event.matches) {
// Stop JavaScript-driven animations
} else {
// Resume animations
}
}
// Listen for system setting changes
motionQuery.addEventListener('change', handleMotionChange);
// Initial check on page load
handleMotionChange(motionQuery);Through both CSS evaluation and JavaScript event listeners, Safari ensures that a user's physical needs configured at the OS level are strictly honored by the web content they consume.