Making a Pastel Color Scheme accessible by adding a High-Contrast Alternative using CSS and JavaScript

Ingo Steinke
3 min readNov 1, 2022

As a front-end web developer, 2022 has been a good year full of innovation, and hopefully, 2023 will continue this trend. New core CSS features, new libraries, and a renewed discussion about accessibility and energy-efficiency help us to unite usability and fancy design in web development.

Inspired by a discussion at a conference earlier this year, I decided to research and put the problem, or instead the 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 I wrote this blog post to reach a greater audience which is also the reason to cross-post on the practical DEV, on Tealfeed, and even on medium.com.

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

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 (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?

So, it all could be as simple as this, but beware, that’s only halfway to the solution:

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

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

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 loaded 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>
.contrast--varies {
transition: background-color 2s ease-out;
}
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 to 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 specific class names.

You can see the final, working workaround on CodePen: https://codepen.io/openmindculture/pen/poKzKrM

This post has originally been published here:

https://dev.to/ingosteinke/how-to-provide-an-accessible-high-contrast-alternative-to-a-pastel-color-scheme-396g

--

--

Ingo Steinke

Sustainable Creative Web Developer in Germany. Helping to build a fast and friendly, accessible, ethical and ecological word wide web.