DEV Community

Ingo Steinke
Ingo Steinke

Posted on • Updated on

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!

Top comments (3)

Collapse
 
yuridevat profile image
Julia 👩🏻‍💻 GDE

I am not sure if I got your question right.

I tried it with my MacBook and everything worked out fine (passed the color test). The darker option was shown after I switched my accessibility preference on my MacOS.

Still, as an Accessibility Advocate I highly recommend using color with high ratio already from the very beginning (in the design process). This doesn't necessarily mean that you don't be able to use pastel colors anymore, but you could use them combined with a dark font color.

Collapse
 
ingosteinke profile image
Ingo Steinke

I have come up with a workaorund, using JavaScript to switch presentation, fading from extreme ultra high contrast colors to more pastel ones using a smooth CSS transition, like in my new Codepen: Fade to Pastel Contrast in an Accessible Fashion ...

... and my StackOverflow answer to my own question:

As a workaround, we can set the high-contrast color scheme as default in CSS, and use JavaScript to apply alternative pastel colors.

Using a timeout prevents false positive color contrast warnings in validation tools that fail to acknowledge that we respect the user's contrast preference, as long as tools are…

I am still not happy about how the color contrast preference UI and validation differs from handling font-sizes (provided natively by browsers) or reduced motion (currently no accessibility criteria yet?), and the "pain in the axe" trying to overcome accesibility validation problems caused by images and color gradients, so I am still open for ideas and suggestions how to default to accessible web design without giving up half of the color palette and many effects that modern CSS has to offer.

Collapse
 
ingosteinke profile image
Ingo Steinke • Edited

I should try to reverse the logic in the code snippet to make high contrast the actual default, not the other way around: codepen.io/openmindculture/pen/eYV.... This validates without color contrast warning, but will this ever show the pastel version? Where could I possibly state that I would prefer less contrast, and how would I know?