Respecting User Preferences

Motion-related Criteria

2.3.1 Three Flashes or Below Threshold — avoid anything that flashes more than three times in any one second period.

2.3.3 Animation From Interactions — motion animation triggered by interaction can be disabled, unless the animation is essential to the functionality or the information being conveyed.

Reducing Motion

We can use the prefers-reduced-motion media query to remove motion for those that have set an operating system setting.

Note that lack of this setting does not necessarily mean a user is OK with motion, as they may just not be aware this setting exists.

In this snippet from Andy Bell's Modern CSS Reset, animations will run once and transtions will happen instantly. Duration is maintained so that any attached JavaScript events (animationend or transitionend) will still complete.

Be sure to test the results as sometimes this may have an unintended consequence of stopping an animation in a less than ideal state.

CSS for "Respecting prefers-reduced-motion"
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

Color and contrast criterion

1.4.3 Contrast Minimum — provide enough contrast between text and its background so that it can be read by people with moderately low vision.

Note that no criteria currently indicate a requirement for “dark mode” or varying contrast modes.

Color and Contrast Feature Media Queries

All media queries adapt to operating system preference

prefers-color-scheme

@media (prefers-color-scheme: dark) {
  /* "dark" mode */
}

@media (prefers-color-scheme: light) {
  /* "light" mode */
}

Learn more about how color-scheme works.

Related property: color-scheme

:root {
  color-scheme: dark light;
}
<meta name="color-scheme" content="dark light">

Related function: light-dark()

Note: Cutting-edge, partial browser support.

This function allows responding to the values of color-scheme with your own custom colors. The first value listed responds to a "light" color-scheme, and the second value to a "dark" color-scheme.

CSS for "Using color-scheme and light-dark()"
:root {
  color-scheme: light dark;
  --text-color: light-dark(mediumvioletred, cyan);
}

p {
  color: var(--text-color);
}

Adjust your color theme preference to see the change of this text color

prefers-contrast

@media (prefers-contrast: no-preference) {}
@media (prefers-contrast: less) {}
@media (prefers-contrast: more) {}
@media (prefers-contrast: custom) {}

Review the spec details for the prefers-contrast media feature.

While not official guidance, the following are considerations for "less" vs "more" contrast from the user experience perspective based on the spec and notes within articles found in the additional resources.

"less" contrast

Helps users with light sensitivity (photophobia), reduces migraine trigger

“more” contrast

Helps users read text & see details, distinguish UI, counter low-vision impairments (ex. Glaucoma)

forced-colors

Increases text legibility through color contrast via built-in or user-defined color palettes.

@media (forced-colors: active) {}
@media (forced-colors: none) {}

active means the user's selected theme will overwrite your palette with system colors.

forced-colors media query intent:

Authoring for feature queries

prefers-color-scheme - provide darker and lighter versions that still fully use brand colors and high-fidelity visuals

prefers-contrast - provide “more” and “less” contrast versions that may require modified palettes and assets

forced-colors - only use to correct for loss or change of color in critical elements

Additional resources