How to provide an accessible high contrast alternative to a pastel color scheme? 🎨

ingosteinke

Ingo Steinke, web developer

Posted on June 8, 2022

How to provide an accessible high contrast alternative to a pastel color scheme? 🎨

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, 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 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, but the following example (also as a codepen here 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?


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

@media (prefers-contrast: more) {
  p {
    background-color: #aa3300;
    color: #ffffff;
  }
}
Enter fullscreen mode Exit fullscreen mode

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 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…

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.

  <div class="contrast--varies contrast--more">
    Some like pastel colors...
  </div>
Enter fullscreen mode Exit fullscreen mode
.contrast--varies {
  transition: background-color 2s ease-out;
}
Enter fullscreen mode Exit fullscreen mode
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);
  }
});
Enter fullscreen mode Exit fullscreen mode

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:

Thoughts and answers are very welcome!

💖 💪 🙅 🚩
ingosteinke
Ingo Steinke, web developer

Posted on June 8, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related