How to provide an accessible high contrast alternative to a pastel color scheme? 🎨
Tags: css, ux, webdev, a11y
Published: 2022-06-08 14:39:46

Inspired by a discussion at a conference, I decided to research and put the problem, or rather challenge, into proper words. I even dared to [ask it as a question on StackOverflow](https://stackoverflow.com/questions/72547565/how-to-provide-an-accessible-high-contrast-alternative-to-a-pastel-color-scheme), although most of my questions tend to get downvoted and deleted, so better make a DEV blog post out of it as well.

How is it possible to ensure a website's color theme offers a high-contrast alternative which complies to the [WCAG 2 minimum contrast requirements](https://webaim.org/articles/contrast/#sc143) while preferring a pastel, low-contrast theme unless the user wants or needs higher contrast?

I tried to define a fallback theme with a higher contrast and providing a lower contrast version unless the user requires high contrast, using the [prefers-contrast media query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-contrast), but the following example (also as [a codepen here](https://codepen.io/openmindculture/pen/OJQBMPQ) which fails the accessibility audit by the axe Chrome extension due to the low contrast of 2.71 of foreground color: #eeeeee, background color: #f26600.)

What CSS code is needed to define a proper fallback? How are the users expected to indicate their contrast preference, and is there a way to make browsers or operating systems adapt the contrast preference based on daylight settings, dark/light theme, ambient light sensors or the like?

{% codepen https://codepen.io/openmindculture/pen/OJQBMPQ %}

```css
p {
  background-color: #f26600;
  color: #eeeeee;
}

@media (prefers-contrast: more) {
  p {
    background-color: #aa3300;
    color: #ffffff;
  }
}
```

{% stackoverflow https://stackoverflow.com/questions/72547565/how-to-provide-an-accessible-high-contrast-alternative-to-a-pastel-color-scheme %}

Update:

## Fade to Pastel Contrast in an Accessible Fashion

As a workaround, we can set the high-contrast color scheme as default in CSS, and use JavaScript to apply alternative pastel colors, but only if there is no preference for higher contrast.

Validation tools might not notice that this time we did respect the users' preferences, but we can set a timeout, so the validations will have passed before changing our styles.

### Perceived False Positives

This can also be used for any other accessibility issues that we perceive as false positives, like not being able to calculate the actual color contrast due to gradients or images, but still triggering a warning just in case.

When we use class names to indicate possible workaround elements, we can also use this same CSS class to apply smooth property transitions, so the switch to the low-contrast pastel colors and gradients looks like an intended fade effect. I could have used CSS custom properties or load an alternative CSS file, as suggested in one of the answers on StackOverflow.

### The Pastel Workaround

The class name based approach uses functional / utility style CSS in the HTML markup and a simple iteration over an HTML element collection after page load, so there is not much overhead added to a site without the pastel workaround.

```html
  <div class="contrast--varies contrast--more">
    Some like pastel colors...
  </div>
```

```css
.contrast--varies {
  transition: background-color 2s ease-out;
}
```

```javascript
document.addEventListener('DOMContentLoaded', () => {
      const prefersMoreContrastQuery = window.matchMedia("(prefers-contrast: more)");
  if (prefersMoreContrastQuery && !prefersMoreContrastQuery.matches) {
    window.setTimeout(() => {
      const moreContrastElements = document.getElementsByClassName("contrast--varies");
      for (let i = 0; i < moreContrastElements.length; i++) {
         moreContrastElements[i].classList.remove("contrast--more");
      }
    }, 5000);
  }
});
```

Using JavaScript to detect the contrast preference instead of relying on CSS media queries solves two problems:

- web browsers seem to ignore `@media (prefers-contrast: less)`
- validation tools seem insist on high color contrast for default styles regardless of any `(prefers-contrast: more)` 
 or `less` media query.

We could switch to pastel colors by loading another CSS file, or modifying CSS custom properties, or removing certain class names.

This is my new working workaround:

{% codepen https://codepen.io/openmindculture/pen/poKzKrM %} 

Thoughts and answers are very welcome!