The CSS contrast-color() function takes a <color> value (as well as a variable) and returns either black or white, whichever is the most contrasting color for that value.
In other words, contrast-color() is sort of an accessibility tool for conforming to WCAG contrast requirements.
.card {
background-color: var(--swatch);
color: contrast-color(var(--swatch));
}
For example, on the next demo update the background color to see the text color change automatically.
The contrast-color() function is defined in the CSS Color Module Level 5 specification.
Syntax
The CSS contrast-color() function syntax is is formatted like this:
contrast-color() = contrast-color( <color> )
Let’s break that down with examples.
Arguments
/* Using a custom variable */
contrast-color(var(--base-background));
/* Passing a color directly */
contrast-color(#34cdf2);
contrast-color(green);
contrast-color() takes a <color> as its only argument and resolves to white or black, depending on which has the highest contrast. If both white and black have the same contrast level, the function defaults to white.
Basic usage
The contrast-color() give us a simple alternative to defining multiple background and text colors, while also ensuring they are contrasting enough. Imagine we had the following scenario:
:root {
--primary-text: #f1f8e9;
--primary-bg: #2d5a27;
--secondary-text: #311b92;
--secondary-bg: #d1c4e9;
--tertiary-text: #002b36;
--tertiary-bg: #ff5722;
}
.primary {
color: var(--primary-text);
background-color: var(--primary-bg);
}
.secondary {
color: var(--secondary-text);
background-color: var(--secondary-bg);
}
.tertiary {
color: var(--tertiary-text);
background-color: var(--tertiary-bg);
}
We defined a text color for each background color in our variables, and if we had more than three possible backgrounds, we’d have had to define them all. Instead, using contrast-color(), we could define only the background color for each theme and let the function return the appropriate contrasting color for the texts.
:root {
--primary: #2d5a27;
--secondary: #d1c4e9;
--tertiary: #ff5722;
}
.primary {
color: contrast-color(var(--primary));
background-color: var(--primary);
}
.secondary {
color: contrast-color(var(--secondary));
background-color: var(--secondary);
}
.tertiary {
color: contrast-color(var(--tertiary-bg));
background-color: var(--tertiary-bg);
}
It is important to note that contrast-color() is still a work in progress (at the time of this writing), and in some cases might not be appropriate from a design standpoint since it only returns black or white. Therefore, I recommend using it only in simple scenarios where either black or white make sense.
In fact, it has some shortcomings that are worth noting.
contrast-color() shortcomings
While contrast-color() appears to improve web accessibility, it has buts we should be aware of before using it.
- It resolves to only black or white texts. Although the draft promises more control in the future, we have to stick to those two colors for now.
- We’re stuck with white when using colors where neither black nor white is a sufficient contrast, or they both have the same contrast.
contrast-color()only works with colors for now. So, in cases where you’re working with text on background images or using font weights to increase contrast, you’ll have to find a different way to meet contrast requirements. And even if it can be technically used with gradients, these too can only go between black to white which might not provide enough contrast between the gradient colors.contrast-color()doesn’t account for thefont-size, which is a defining criterion, in choosing a contrast color. Hopefully, this will be accounted for in the future.
So, at the time of writing, it seems it’s better to manually define colors that are contrasting enough in our themes as contrast-color() isn’t really feasible right now.
Older syntax
Based on earlier articles, the contrast-color() function used to take multiple color arguments–the base color versus multiple contrasting color options to choose from:
contrast-color(var(--bg) vs red, lightgreen, blue)
This syntax no longer exists in the draft. It’s one color and one color only.
Specification
The contrast-color() function is defined in the CSS Color Module Level 5 specification.
Browser support
While browser support is limited at the time of this writing, it’s a good idea to include a fallback if you’re planning to use it on a project. We can use the @supports at-rule to detect if the browser understands the function:
.card {
--bg-color: #2d5a27;
background-color: var(--bg-color);
/* Default Fallback */
color: ghostwhite;
}
/* Use the function if supported */
@supports (color: contrast-color(red)) {
.card {
color: contrast-color(var(--bg-color));
}
}
Further reading:
- Manage Accessible Design System Themes With CSS Color-Contrast() (Daniel Yuschick)
Article
on
Feb 11, 2026
Approximating contrast-color() With Other CSS Features
Article
on
Jun 5, 2025
Exploring the CSS contrast-color() Function… a Second Time
Link
on
Oct 8, 2025
The thing about contrast-color
contrast-color() originally handwritten and published with love on CSS-Tricks. You should really get the newsletter as well.