In various countries, web accessibility is a legal requirement, with significant penalties for non-compliance. This necessitates optimal color contrast for text and icons as per the Web Content Accessibility Guidelines (WCAG). While many color contrast checkers exist, including one in Figma, the upcoming `contrast-color()` function doesn’t just check contrast; it determines whether black or white provides the best contrast with a chosen color.
Previously, this feature was discussed under the name `color-contrast()`, which was more complex. It first appeared in Safari Technology Preview 122 in 2021, and remains available in version 220.
Here’s how you use it:
“`css
button {
–background-color: darkblue;
background-color: var(–background-color);
color: contrast-color(var(–background-color));
}
“`
In this example, `contrast-color()` resolves to white, which contrasts better with `darkblue`. However, the function has limitations, including limited browser support (only in Safari Technology Preview).
You can conditionally use `contrast-color()`:
“`css
@supports (color: contrast-color(red)) {
/* contrast-color() supported */
}
@supports not (color: contrast-color(red)) {
/* contrast-color() not supported */
}
“`
### The shortcomings of `contrast-color()`
Improvements are being considered, but currently, `contrast-color()` resolves only to black or white. If neither is accessible against the chosen color, it may not provide a contrasting color. Ideally, it should resolve to the closest accessible variant of a preferred color.
`contrast-color()` only accepts `
“`css
button {
background: linear-gradient(to right, red, blue);
span {
background: linear-gradient(to right, contrast-color(red), contrast-color(blue));
color: transparent;
background-clip: text;
}
}
“`
The gradient issue arises because `contrast-color()` only resolves to black or white, resulting in a grey-purple mix. This could be solved by allowing a wider color spectrum.
Font size affects color contrast criteria, but `contrast-color()` doesn’t currently consider it. APCA (Accessible Perceptual Contrast Algorithm) is a new algorithm for measuring color contrast, offering more nuanced criteria considering a wider range of font sizes and weights.
`contrast-color()` doesn’t use APCA, but the draft spec suggests offering more algorithms in the future, possibly allowing choice between APCA and WCAG algorithms. Some countries require WCAG 2 compliance, while others will require WCAG 3 when it becomes a standard.
APCA is not yet part of WCAG 3, nor is `contrast-color()`. For now, `contrast-color()` uses WCAG 2 only.
### Using `contrast-color()`
Here’s an example of a `darkblue` button with text color chosen by `contrast-color()`:
“`css
button {
–background-color: darkblue;
background-color: var(–background-color);
color: contrast-color(var(–background-color));
}
“`
And with `lightblue`:
“`css
button {
–background-color: lightblue;
background-color: var(–background-color);
color: contrast-color(var(–background-color));
}
“`
You can use `contrast-color()` on `background-color` or any `
“`css
button {
–color: darkblue;
color: var(–color);
background-color: contrast-color(var(–color));
}
“`
Any valid `
“`css
button {
–background-color: hsl(0 0% 0%);
background-color: var(–background-color);
color: contrast-color(var(–background-color));
}
“`
Change the base color dynamically (e.g., on hover):
“`css
button {
–background-color: hsl(0 0% 0%);
background-color: var(–background-color);
color: contrast-color(var(–background-color));
&:hover {
–background-color: hsl(0 0% 50%);
}
}
“`
Use `contrast-color()` with `light-dark()` for accessible contrast in light and dark modes:
“`css
:root {
&:has(input[type=”checkbox”]:checked) {
color-scheme: dark;
}
&:not(:has(input[type=”checkbox”]:checked)) {
color-scheme: light;
}
body {
background: light-dark(hsl(0 0% 50%), hsl(0 0% 0%));
color: light-dark(
Discover more from WIREDGORILLA
Subscribe to get the latest posts sent to your email.