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:

  1. no-preference: The default state when "Increase Contrast" is turned off.
  2. 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.