CSS contrast-color() Function
The CSS contrast-color() function automatically selects either black or white based on a specified color.
It is useful for choosing text colors that contrast with button backgrounds, labels, cards, and other interface elements. The function reduces the need to manually maintain separate foreground and background color values.
Syntax
contrast-color(color)
The function accepts one CSS color value and returns either black or white.
For example:
.button {
background-color: navy;
color: contrast-color(navy);
}
The browser selects white text because white provides greater contrast against navy.
Additional examples:
color: contrast-color(black);
color: contrast-color(white);
color: contrast-color(#0066cc);
color: contrast-color(rgb(255 200 0));
color: contrast-color(hsl(220 80% 40%));
color: contrast-color(var(--background-color));
The function can be used anywhere a compatible CSS <color> value is accepted.
Unlike contrast(), it is not a filter function and does not accept a contrast adjustment percentage.
Parameters
The contrast-color() function requires one parameter.
| Parameter | Description |
|---|---|
color |
A valid CSS <color> value used as the reference for selecting a contrasting color. |
The input can be a named color, hexadecimal color, CSS color function, or a custom property that resolves to a color.
For example:
contrast-color(#222222)
contrast-color(lightyellow)
contrast-color(rgb(20 100 180))
contrast-color(oklch(60% 0.15 250))
Only one color argument is accepted.
The following is invalid because it supplies two colors:
contrast-color(red, blue)
The function does not accept a list of candidate colors or a custom contrast threshold in its current standardized syntax.
How It Works
The browser evaluates the supplied color and selects whichever of black or white provides greater contrast against it.
For example:
.dark-button {
background-color: #222222;
color: contrast-color(#222222);
}
.light-button {
background-color: #eeeeee;
color: contrast-color(#eeeeee);
}
The dark button receives white text, while the light button receives black text.
The browser determines the result automatically. The exact contrast calculation used to choose between black and white is defined by the browser implementation.
When black and white provide equal contrast, the function returns white.
The function does not change the original color. It generates a separate color value that can be assigned to a CSS property.
For example:
.notice {
background-color: #ffcc00;
color: contrast-color(#ffcc00);
}
The background remains yellow, while the text color is selected automatically.
Return Values
The current contrast-color() function returns one of two named colors.
| Return Value | Meaning |
|---|---|
black |
Selected when black provides greater contrast against the input color. |
white |
Selected when white provides greater contrast, or when both choices provide equal contrast. |
For example:
contrast-color(black)
contrast-color(white)
These return white and black, respectively.
The function cannot directly return gray, yellow, blue, or another custom foreground color.
It also does not return a numeric contrast ratio.
Because browser implementations may use different contrast algorithms, avoid assuming that every intermediate color produces the same choice in every browser.
Using Custom Properties
The contrast-color() function works with CSS custom properties, allowing foreground colors to respond automatically when a background color changes.
For example:
:root {
--button-background: #0066cc;
}
.button {
background-color: var(--button-background);
color: contrast-color(var(--button-background));
}
The custom property supplies the background color to both declarations.
If the background color changes, the contrasting text color is recalculated.
For example:
.button-primary {
--button-background: #003366;
}
.button-warning {
--button-background: #ffcc00;
}
.button-success {
--button-background: #228844;
}
Each button can use the same base styling while selecting an appropriate black or white text color.
This approach reduces the need to create separate text-color variables for every background color.
Using with Background Colors
Although the function is commonly used to select text colors, it can also select a background color that contrasts with a specified foreground color.
For example:
.label {
color: navy;
background-color: contrast-color(navy);
}
The label receives a white background to contrast with the navy text.
Another example:
.label {
color: #eeeeee;
background-color: contrast-color(#eeeeee);
}
The background becomes black, providing contrast with the light text.
For reusable styling:
.label {
--label-color: #003366;
color: var(--label-color);
background-color: contrast-color(var(--label-color));
}
The function selects a color based on the supplied input, not by automatically examining whatever background happens to be behind an element.
When a background is transparent, patterned, or an image, a single contrasting color may not remain readable across the entire area.
Light and Dark Color Schemes
The contrast-color() function can be combined with media queries to select text colors for light and dark themes.
For example:
:root {
--panel-background: #f0f0f0;
}
@media (prefers-color-scheme: dark) {
:root {
--panel-background: #222222;
}
}
.panel {
background-color: var(--panel-background);
color: contrast-color(var(--panel-background));
}
In light mode, the panel uses a light background with black text.
In dark mode, it uses a dark background with white text.
The foreground color is selected from the current value of --panel-background.
This can simplify theme stylesheets when many elements share reusable background colors.
For more complex designs, manually defined foreground and background pairs may still provide better control over readability and visual appearance.
Fallback Colors
Because contrast-color() is a newer CSS feature, provide a conventional color declaration for browsers that do not support it.
For example:
.button {
background-color: #003366;
color: #fff;
color: contrast-color(#003366);
}
Browsers that do not recognize the function retain the earlier white text color.
Browsers that support the function use the automatically selected color.
For a feature-specific rule, use @supports:
.button {
background-color: #003366;
color: #fff;
}
@supports (color: contrast-color(black)) {
.button {
color: contrast-color(#003366);
}
}
The fallback should be chosen for the actual background color so the text remains readable in unsupported browsers.
When using multiple background colors, provide appropriate fallback text colors for each variation.
Example
The following example demonstrates automatic text color selection for four different background colors.
HTML:
<div class="contrast-color-demo">
<div class="contrast-color-sample cc-navy">Navy</div>
<div class="contrast-color-sample cc-yellow">Yellow</div>
<div class="contrast-color-sample cc-dark">Dark Gray</div>
<div class="contrast-color-sample cc-light">Light Gray</div>
</div>
CSS:
.contrast-color-demo {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.contrast-color-sample {
display: flex;
align-items: center;
justify-content: center;
width: 120px;
height: 80px;
border: 1px solid #ccc;
font-weight: bold;
}
.cc-navy {
background-color: #003366;
color: #fff;
color: contrast-color(#003366);
}
.cc-yellow {
background-color: #ffcc00;
color: #000;
color: contrast-color(#ffcc00);
}
.cc-dark {
background-color: #222222;
color: #fff;
color: contrast-color(#222222);
}
.cc-light {
background-color: #eeeeee;
color: #000;
color: contrast-color(#eeeeee);
}
Dark backgrounds receive white text, while light backgrounds receive black text.
The fallback colors provide the same intended appearance when contrast-color() is unsupported.
Custom Property Example
This example uses one reusable CSS rule to select text colors for buttons with different background colors.
HTML:
<div class="contrast-button-demo">
<button type="button" class="contrast-button button-blue">Blue</button>
<button type="button" class="contrast-button button-gold">Gold</button>
<button type="button" class="contrast-button button-purple">Purple</button>
</div>
CSS:
.contrast-button-demo {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.contrast-button {
padding: 12px 20px;
border: 0;
background-color: var(--button-background);
color: var(--button-fallback);
font: inherit;
font-weight: bold;
cursor: pointer;
}
.button-blue {
--button-background: #003366;
--button-fallback: #fff;
}
.button-gold {
--button-background: #ffcc00;
--button-fallback: #000;
}
.button-purple {
--button-background: #663399;
--button-fallback: #fff;
}
@supports (color: contrast-color(black)) {
.contrast-button {
color: contrast-color(var(--button-background));
}
}
The background colors are defined separately, while the supported browser selects each button's text color automatically.
The fallback custom properties provide readable text colors in older browsers.
contrast-color() vs. contrast()
The contrast-color() and contrast() functions have different purposes.
| Feature | contrast-color() | contrast() |
|---|---|---|
| Function type | CSS color function. | CSS filter function. |
| Purpose | Selects a contrasting black or white color. | Adjusts the contrast of rendered content. |
| Input | One CSS color. | An optional number or percentage. |
| Return value | Black or white. | A filter function value. |
| Typical property | color or background-color. |
filter or backdrop-filter. |
For example:
.first {
background-color: navy;
color: contrast-color(navy);
}
.second {
filter: contrast(150%);
}
The first declaration selects a text color. The second increases the visual contrast of the rendered element.
These functions are not interchangeable.
Accessibility
The contrast-color() function can help improve text readability by choosing between black and white, but it does not guarantee that every design will meet all accessibility requirements.
WCAG 2.2 Level AA generally requires a minimum contrast ratio of 4.5:1 for normal text and 3:1 for large text.
The function selects black or white according to the browser's contrast algorithm. The exact algorithm is not fixed by the current specification.
Even when a color pair meets a numerical contrast requirement, readability can be affected by font size, font weight, transparency, surrounding colors, and other visual conditions.
For example:
.notice {
background-color: #2277d3;
color: contrast-color(#2277d3);
}
Some intermediate colors can produce results that are difficult to read despite the browser selecting its preferred contrasting color.
For important text, verify the actual foreground and background colors using an accessibility contrast checker.
Do not rely on contrast-color() alone for text displayed over photographs, gradients, or changing backgrounds.
Common Uses
The contrast-color() function is useful when foreground and background colors need to remain coordinated.
| Use | Description |
|---|---|
| Buttons | Automatically select black or white text for button backgrounds. |
| Badges and labels | Keep text readable on different solid background colors. |
| Cards | Generate foreground colors from card background variables. |
| Light and dark themes | Adjust text colors when a theme background changes. |
| Design systems | Reduce the number of manually maintained foreground and background color pairs. |
| Dynamic interfaces | Choose text colors when background colors are changed through CSS custom properties. |
For example, a reusable badge can use:
.badge {
--badge-background: #003366;
background-color: var(--badge-background);
color: #fff;
color: contrast-color(var(--badge-background));
}
Changing the custom property allows the same CSS rule to work with different badge colors.
Limitations
The contrast-color() function has several important rules and limitations.
- It accepts exactly one CSS color argument.
- It currently returns only
blackorwhite. - It does not return a contrast ratio or a custom color.
- It does not accept a percentage for adjusting contrast.
- The precise contrast selection algorithm is browser-defined.
- It does not automatically inspect an element's rendered background.
- Transparent, patterned, and image backgrounds require additional consideration.
- The selected color does not guarantee readability in every situation.
- Older browsers may require conventional fallback colors.
For example, this is valid:
color: contrast-color(#003366);
However, this is invalid because no color is supplied:
color: contrast-color();
The following is also invalid because the function does not accept a percentage:
color: contrast-color(#003366 150%);
Use contrast() with the filter property when the goal is to increase or decrease visual contrast rather than select a foreground color.
Browser Support
The CSS contrast-color() function is Baseline Newly available. It has been supported across the latest major browser engines since April 2026.
Older browser versions may not recognize the function, so a fallback color is recommended.
For example:
.button {
background-color: #003366;
color: #fff;
color: contrast-color(#003366);
}
Browsers without support retain the white text color.
Feature detection can also be used:
@supports (color: contrast-color(black)) {
.button {
color: contrast-color(#003366);
}
}
For current compatibility information, visit Can I Use? and search for CSS contrast-color().
Specifications
The contrast-color() function is defined in the CSS Color Module Level 5 .
The specification defines the function's color argument, black-or-white return values, and browser-defined contrast selection behavior.
Related CSS features include contrast(), color-mix(), light-dark(), CSS custom properties, and the prefers-color-scheme media feature.
