contrast-color() makes text contrast a browser guarantee

A black and white striped lighthouse on Murano beside a choppy Venetian lagoon

The April web platform digest on web.dev has a feature I have wanted for years. The CSS contrast-color() function is now Baseline Newly available: Chrome and Edge 147, Firefox 146, and Safari 26 all ship it. Hand it a background color and it returns black or white, whichever has more contrast. The browser does the arithmetic, every time, for every color the background could ever be.

The rest of the month is also worth a look. Firefox 150 adds ariaNotify(), a way to announce something to a screen reader without the hidden live region hack, and the auto keyword for the sizes attribute on lazily loaded images. Chrome 147 scopes view transitions to individual elements instead of the whole document, and ships border-shape for borders that follow a custom path.

But contrast-color() is the one I think changes how a design system is built. Most systems I have seen ship pairs: a surface token and its matching text token, chosen by a person and verified by a person, for every surface in the palette. Every new surface means a new pair and a new contrast check, and every theme multiplies the work.

With contrast-color() in every engine, the text color for a surface is a function of the surface. The pair collapses into one token. My view is that a design system still carrying hand-paired text tokens is now paying a maintenance cost for no accessibility gain, and the next time the palette changes is the moment to stop.

How many color pairs does your design system maintain by hand?

Photo source: https://photos.robertstowe.com/venice