CSS contrast-color is newly baseline, but it falls short in some areas.
-
CSS contrast-color is newly baseline, but it falls short in some areas. Here's how it works, and what to look out for:
-
CSS contrast-color is newly baseline, but it falls short in some areas. Here's how it works, and what to look out for:
@firefoxwebdevs fun fact, you can (kind of) make it output colors other than white or black, using relative color syntax! For example, if you wanted yellow instead of white (for whatever reason), you could do `rgb(from contrast-color(var(--my-color)) r g 0)`. This doesn't account for the changed color when deciding the most contrasty color, though, so I reckon this is only useful for very minor color changes (like a slightly off-white or nearly-black).
-
CSS contrast-color is newly baseline, but it falls short in some areas. Here's how it works, and what to look out for:
You can often get a better result using this trick with oklch() by @khamer which approximates APCA https://random-stuff.jakearchibald.com/color-contrast/#2277d3
-
@firefoxwebdevs fun fact, you can (kind of) make it output colors other than white or black, using relative color syntax! For example, if you wanted yellow instead of white (for whatever reason), you could do `rgb(from contrast-color(var(--my-color)) r g 0)`. This doesn't account for the changed color when deciding the most contrasty color, though, so I reckon this is only useful for very minor color changes (like a slightly off-white or nearly-black).
@vrugtehagel yesss, you can also use similar tricks to approximate APCA https://random-stuff.jakearchibald.com/color-contrast/#2277d3
-
You can often get a better result using this trick with oklch() by @khamer which approximates APCA https://random-stuff.jakearchibald.com/color-contrast/#2277d3
@firefoxwebdevs
For folks reading into this thread, understand that APCA is not part of any W3C spec, draft or otherwise:
https://adrianroselli.com/2026/04/wcag3-contrast-as-of-april-2026.htmlYou can still use APCA (whichever APCA version), but the colors you choose may not satisfy WCAG. Be sure to also check them against WCAG.
-
You can often get a better result using this trick with oklch() by @khamer which approximates APCA https://random-stuff.jakearchibald.com/color-contrast/#2277d3
@firefoxwebdevs @khamer Here's a useful resource for checking color contrast: https://webaim.org/resources/linkcontrastchecker/
In my own code, and I'm ashamed I didn't save links to how I found these values, I calculate contrast-color manually in JS like this (assuming values for the background's
r,b, andgof 0-255):let luminance = r / 1199 + g / 357 + b / 3532; // 0-1
let foreground = luminance > .63 ? "#000" : "#fff";I also emphasize it more with text shadow, giving a subtly glowing outline around the text:
elem.style.textShadow = "0 0 .3ex " + (luminance > .63 ? "#fff" : "#000"); -
@firefoxwebdevs @khamer Here's a useful resource for checking color contrast: https://webaim.org/resources/linkcontrastchecker/
In my own code, and I'm ashamed I didn't save links to how I found these values, I calculate contrast-color manually in JS like this (assuming values for the background's
r,b, andgof 0-255):let luminance = r / 1199 + g / 357 + b / 3532; // 0-1
let foreground = luminance > .63 ? "#000" : "#fff";I also emphasize it more with text shadow, giving a subtly glowing outline around the text:
elem.style.textShadow = "0 0 .3ex " + (luminance > .63 ? "#fff" : "#000");@adamhotep @khamer that's cool, but just be aware of the cases where WCAG gets it wrong (that page uses WCAG)
-
@adamhotep @khamer that's cool, but just be aware of the cases where WCAG gets it wrong (that page uses WCAG)
@firefoxwebdevs @khamer yeah, iirc I tweaked the formula a bit, but I also did some unit conversion, so it's harder to see that.
-
CSS contrast-color is newly baseline, but it falls short in some areas. Here's how it works, and what to look out for:
@firefoxwebdevs Thanks for reminding me how to pronounce WCAG
-
@firefoxwebdevs Thanks for reminding me how to pronounce WCAG
@simevidas I was actually shocked whisperx picked it up correctly.