CSS Color-Contrast(): A Step-By-Step Guide

Aman Mandal

Posted On: March 3, 2023

view count212966 Views

Read time16 Min Read

CSS Color-Contrast

Have you ever come across a website and literally got frustrated because you were having trouble using it? Maybe because the text size was too small, or perhaps it’s using some WebGL/Three.js technology that your browser doesn’t support, or the font color and contrast were too weird.

If you think back to these annoying experiences where you could not navigate through a website correctly, there’s a high probability that you’ve experienced inaccessibility in one form or another. It creates an overlap between unpleasant user experience and inaccessibility.
For example, if you found yourself struggling to read small texts on a particular website, the chances are a visually impaired person wouldn’t be able to read at all.

And somehow, if you are a designer and manage to design a website with a better font size, you would improve the experience and accessibility for all the users, including those with visual impairments. To build and launch an accessible website, the CSS color-contrast() feature can help developers provide adequately contrasting and accessible user interfaces where everyone can easily access and use information and services.

By considering the needs of visually impaired and disabled individuals during the design process, we can build websites that are easy to navigate and understand for everyone. This means using clear and concise language, providing alternative text for images, and using structured layouts that are easy to understand.

By following these principles, we can create an inclusive web accessible to all users and promote equality and inclusivity. And in this guide, we particularly see how the CSS color-contrast() helps us to create accessible user interfaces.

What is Accessibility?

The term ‘Accessibility,’ sometimes shortened to Ally, means the web design that works for everyone despite their language, location, ability, or hardware (device). Accessible design is not just about accommodating attention to people with permanent disabilities but creating a seamless experience for all users regardless of their abilities. It’s about designing a website that is easy to navigate, understand, and use for everyone, including those with physical impairments.

Accessibility is crucial for creating a positive user experience for all individuals, including those with impairments. By ensuring that all users can easily navigate and access the information they need, we are promoting inclusivity and equality in the digital space. This benefits those with special needs and enhances the overall user experience. Check our tutorial on accessibility testing to learn more.

According to a survey by the World Health Organization, approximately 16% of the world’s population lives with some form of disability, which is expected to increase with an aging population. This means that a significant proportion of internet users may have difficulties accessing traditional websites.

By designing for accessibility, we can not only make the internet a more inclusive place for people with disabilities but also create new opportunities for businesses. Accessible websites can increase the potential customer base, provide a better user experience, and improve the brand reputation.

One way to achieve this is by adhering to the Web Content Accessibility Guidelines (WCAG) developed by the World Wide Web Consortium (W3C). These guidelines provide specific recommendations for creating accessible digital content, including guidelines for text contrast.

The WCAG recommends a minimum contrast ratio of 4.5:1 between text and its background to ensure that text is easy to read for all users, including those with visual impairments. By following these guidelines, designers can create websites that are accessible and user-friendly for all users, regardless of their abilities.

So, considering the contrast ratio of text and background will not only enhance the user experience of visually impaired people and all users in general. And this ease of use, specifically considering visually impaired individuals, is the foundation for creating accessible modern web designs.

Why is Web Accessibility important?

Many designers used to think that accessibility is a ‘nice to have’ feature when designing, but now accessibility is no longer considered an optional feature and has become a necessity for many organizations.

According to a report by the WebAIM organization, 96.8% of home pages studied had WCAG2 failures. Having accessibility at the top of the mind while designing a user interface (UI) will improve the user experience for not only disabled individuals but also for the general user as well.

By the way, It’s one thing to require alt text on an image element or a label for an input element, but enforcing color palettes is entirely different. So, now let’s look at how this CSS color-contrast() will help us with that!

Subscribe to the LambdaTest YouTube Channel and stay updated with the latest tutorials around Selenium testing, Playwright, Appium, and more.

Overview of CSS color-contrast() function

While writing this article, CSS color-contrast() is an experimental feature, and it’s a part of CSS Color Module Level 5.

Currently, the CSS color-contrast() feature is only available in Safari (TP). And you can turn on the feature in the Develop and Experimental Features menus.

Overview of CSS


Note: Below are CodePen examples that may not work if you are not using the above-recommended browser.

The main purpose of this feature is to select the ideal contrasting color from a list when compared against a base color.

CodePen examples


Our article refers to the first parameter as the “base color” and the second parameter as the “color list.” The CSS color-contrast() function can accept any browser-supported CSS color formats like

  • Hexadecimal (#ff3300)
  • RGB (rgb(255, 0, 0))
  • RGBA (rgba(25, 32, 65, 0.86))
  • HSL colors (hsl(120, 100%, 125%))

There’s also a third parameter to the function which is target contrast, but we will talk about it in the later part of this blog.

Getting Started with CSS color-contrast()

The CSS color-contrast() function ensures that text on a webpage has enough contrast with its background for easy readability. This is particularly important for visually impaired users who may struggle to read text with low contrast.

From Rachel Andrew’s talk at AxeCon 2022, New CSS With Accessibility in Mind, we come to know how big of an impact a CSS feature can have in the world of accessible design.

Rachel also demoed the new feature by dynamically defining text colors based on the background colors. Here is the CodePen example for CSS color-contrast().

So, let’s take a quick look at this feature by setting some background colors and text colors.

In the above code block, we defined the –primary-background custom property as a shade of dark grey, #1e1e1e. And then, we used the same property as the base color in the color-contrast () function and compared it against each item in the color list to find the highest contrasting value.

Now let’s take it a little further and try to experiment with the function. We can effectively chain the color-contrast () functions by simply using the result of the base color of another function. This sounds tough, but let’s take the previous example of .content only and try to chain it!

In the above code block, we defined the –primary-background custom property as a shade of dark grey, and we use the same custom property as the base color in the color-contrast() function and then compared it with the items in the color list, i.e., white and black and stored it in a custom variable called –primary-color. Then in the .content class, we used the background color and the color as variables, but here comes the interesting part!

Inside the content class, we changed the text color of all the paragraphs (p tag) by chaining the color-contrast () function. We simply used the –primary-color variable, i.e., a color derived using the color-contrast () we defined earlier in the root as the base color. We compared it with the items in the color list.

Here’s the complete example.



See the Pen
Simple Demo (color-contrast)
by Aman Mandal (@aman-mandal)
on CodePen.

The above code is an example of how to use the CSS color-contrast() function to ensure that text color meets the minimum recommended contrast ratio as defined in the WCAG. It uses the CSS color-contrast() function to compare the contrast ratio of the text color against the background color and assigns a new class to the text if the contrast ratio is not met. This helps ensure that text is legible for all users, including those with visual impairments.

By using the CSS color-contrast() function, the code can automate the process of checking for contrast ratios and enhance the user experience for all users. The above code is an example of how to implement accessibility features in a website. It adds value to accessibility by providing a simple and efficient way to ensure that text is legible for all users, including those with visual impairments.

But we can take it further using the ::selection pseudo-element. Here’s how we can implement it.



See the Pen
color-contrast() :: selection
by Aman Mandal (@aman-mandal)
on CodePen.

 CSS color-contrast

In the above code block, we used the CSS color-contrast() function with the ::selection pseudo-element, and as you can see how effective it is!

But the color-contrast() function isn’t limited to only comparing HEX codes (#000000). The previous example can be tweaked to use different color types simultaneously while returning the same results.

The color-contrast() function can simply chain HSL colors, RGBA colors, RGB colors, etc. at the same time without giving any potential errors. So, because of this particular feature, working with contrasts will be easier and more accessible.

CSS Color-Contrast() with Pseudo Classes

We have used the ::selection pseudo-element with CSS color-contrast() function, and setting colors dynamically while selecting fonts is fascinating. But it’s more of a static thing, like text colors and backgrounds won’t change after they are rendered.

So, let’s look at something much more intriguing, i.e., changing contrasts on interactive elements and their CSS pseudo-classes.

When navigating through a website, we sometimes use only our keyboard, and there are a variety of tab stops along the way, like buttons, input elements, links inside the body, and maybe a linked image or a card. While each element must have a compliant focus indicator, it’s not easy to create a focus pseudo-element for all the elements present. And here, color-contrast() can help!

Let’s see what is going on in the above snippet.

The —background-button custom property is used as the base color in the color-contrast() function for selecting the value of —button-text-color. Anytime the —background-button changes, the custom —button-text-color will also change because they are chained. Then we defined —button-hover custom property for the :hover pseudo-element.

Now comes one of the most important pseudo-element when talking about accessibility, the :focus element. The :focus style is where the color-contrast() function can be expanded by using the —background-primary custom property as the base color in the function. It’s compared to the current style of button, which provides the ability to have contextually-aware focus styles.

Let’s take a look at the example and try to understand it better.



See the Pen
color-contrast() :hover & :focus
by Aman Mandal (@aman-mandal)
on CodePen.


As you can see in the above example, we have used the color-contrast() function with pseudo-classes. Stephanie Eckle’s presentation on “Modern CSS Upgrades To Improve Accessibility” provides a detailed and clear overview of various CSS upgrades that can improve accessibility for users. The presentation covers topics such as CSS color-contrast(), semantic HTML, and responsive design and offers clear examples to illustrate the concepts. The presentation is a great resource for those looking to improve the accessibility of their websites.

Target Contrast Ratio

In the beginning of this article, I talked about the optional third parameter for the CSS color-contrast() function. Now let’s dig deeper into this feature.


The optional third parameter for the color-contrast() function defines a target contrast ratio. The parameter accepts either a keyword — AA, AA-large, AAA, and AAA-large – or a number. When a target contrast is defined, the first color from the color list that meets or exceeds it is selected.

Let’s take a look at an example to understand the feature properly.




See the Pen
Target Contrast Ratio
by Aman Mandal (@aman-mandal)
on CodePen.

When the target contrast ratio is defined, the color-contrast() function will return the very first value from the color list that meets the target. However, when no value in the color list meets the target contrast, that’s where the magic happens!

As you can see in the above code snippet, the base color is black(#000), and the color list consists of two dark shades of grey, but no value would meet the AA(4.5) target contrast. So what will happen then?

CSS will fill in the blanks if the color list doesn’t contain a value that meets the target contrast – either black or white. In this case, color-contrast() could enable designers to enforce a specific level of accessibility.

Let’s have a look at the above code snippet and try to understand the target ratio.

The base .background-primary class does not use a target contrast. And this results in the color being defined as #222, the highest contrasting value from the color list relative to the base color, black. But is the color #222 (another black shade) accessible here? The clear answer is a NO!

Now let’s compare this to when the .background-primary and the .with-target-ratio classes are combined, and a target contrast is specified. The results are very different despite using the same base color and color list. If none of the colors in the color list meet the AA contrast target, the function chooses the color that does. In this case, White!

Inevitable Drawbacks of CSS color-contrast()

As we know, the CSS color-contrast() function is still an experimental feature, so there are many improvements at the time of writing this article. Let’s look at what they are and how to deal with them!

  • Visual Contrasts and Colors are not the same
  • When using the color-contrast() function, it’s just comparing the text color with the background color. Yes! Just exactly that. It’s not considering the other properties or styles that affect visual contrasts, e.g., font-size, opacity, font-weights, etc.

    This means that it’s possible to have a correct color contrast but still inaccessible because of the other styles and properties. For example, if a website has a white background and black text, the color contrast is technically correct.
    However, if the font size is very small, it will be difficult for visually impaired users to read the text. Similarly, if the text has a very low opacity, it will be difficult to read for all users. In both cases, even though the color contrast is technically correct, the text is not accessible due to other typography issues.

  • Highest contrast doesn’t mean the accessible one
  • As we mentioned earlier, the CSS color-contrast() function can control the color and themes but still, there are limitations at this very moment that can’t be ignored. When the function compares the base color and the colors from the color list and no target ratio (third parameter) is specified, it will simply select the highest contrasting color from the list.

    Just because the two colors, i.e., the base color and the color selected from the list, provide an excellent contrast ratio, it doesn’t mean it’s accessible.

    In this above code snippet, we have used black (#000) as the background color, and it is compared to the two darker shades of gray, i.e., #1e1e1e and #222. And as we know, the #222 color would be selected by the color-contrast() function for having the highest contrast, but does this color an accessible one? NO! But as we haven’t used the third parameter, there’s no other choice.

  • No Gradients support as of now
  • At the time of writing this article, the Gradients are not supported in the color-contrast() function. Which also makes sense. Imagine, if there’s a background color with a gradient of green to yellow, what would be the base color? And how will you decide on colors for the color list?

    However, a small codepen below by Michelle Barker has experimented using the color-mix() and color-contrast() functions together to support the use case.

See the Pen
color-mix + color-contrast (Safari TP only)
by Michelle Barker (@michellebarker)
on CodePen.

It’s a Wrap!

That was a lot to take in, but let’s quickly review what we’ve learned about the CSS color-contrast() function.

So, the color-contrast() function is an experimental feature that selects the greatest contrasting color. It takes three arguments: the base color, the color list, and the target contrast ratio (optional). The CSS color-contrast() simply compares the base color to the color list and returns the highest contrasting color, which helps to improve accessibility on the web on a much larger scale.

Once the spec has been implemented and supported by browsers, the color-contrast() function can be the game-changing feature. There are plenty of unexplored areas and use cases for CSS color-contrast(). In the near future, we are hoping to see this feature on all browsers so that we all can start using it. Until then, keep experimenting and keep building.

Frequently Asked Questions (FAQs)

What is color contrast in CSS?

Color-contrast() in CSS compares a color value with a list of other color values, selecting the one with the highest contrast.

What is the color contrast AA vs. AAA?

Level AA needs a minimum contrast ratio of 4.5:1 for normal text and 3:1 for larger text. Further, it requires a contrast ratio of at least 3:1 for GUI components. On the other hand, Level AAA requires at least a contrast ratio of 7:1 for normal text and 4.5:1 for larger text.

Author Profile Author Profile Author Profile

Author’s Profile

Aman Mandal

Aman Mandal is a front-end developer and technical writer. He writes blogs on front end technologies like HTML, CSS, and JavaScript. When not coding, he participates in Twitter spaces. He is based out of Mumbai, India.

Blogs: 3