Harrison Merrill - Practice Site

WDD 331R Advanced CSS - Postprocessing the Cascade
Color scheme

contrast-Color()

How It Works

The contrast-color() function analyzes the background color and determines whether black or white text would provide better contrast. It uses the WCAG contrast ratio formula to target a contrast ratio of 4.5:1, which makes it always try to meet accessibility standards for readability (but it has some limitations).

This is particularly useful for dynamic content, user-generated themes, or any situation where you can't predict the background color in advance. By using contrast-color(), you can ensure that your text remains legible and accessible regardless of the background.

Live Demo

- Copied from BYU-I Live Demo

Pick a background color with the color input below and watch contrast-color() decide whether the text should be black or white. Pay attention to mid-tone colors where the result may look questionable. Use the theme toggle to see how the demo container responds in both light and dark mode:

#8464c4
Your browser does not support contrast-color(). Try Chrome 133+, Firefox 146+, or Safari 18.4+.
Text Tint (lighter)
Text Base color
Text Shade (darker)

How to Write the Code

Using contrast-color() is easy, and can be used anywhere where you'd use a color value. For example:


				.element {
					background-color: var(--some-bg-color);
					color: contrast-color(var(--some-bg-color));
				}

In this example, the text color will automatically adjust to either black or white based on the value of --some-bg-color. If your using a token system that adjusts the background color of an object based on content, highlight or hover state, whether it has been clicked or not, or based on light and dark modes, it will dynamically decide whether to appear in white or black based purely on the contrast ratio - no javascript required.

While browser support is strong, its a good idea to wrap your contrast-color() in an @supports block for safe fallbacks. This may look something like this:


					.element {
						background-color: var(--some-bg-color);
						color: #000; /* Fallback color */
					}

					@supports (color: contrast-color(red)) {
						.element {
							color: contrast-color(var(--some-bg-color));
						}
					}

While this is a little bit of extra work, it ensures that if the browser does not support contrast-color (in this case by testing it with the simple red color), it will fail gracefully to your specified fallback. @supports should be placed at the top level, not inside a nested block, but may be placed near the bottom of the cascade, with all your @supports rules nested together, or in a separate stylesheet if you're trying to juggle support for many types of things.

Limitations

While contrast-color() is a powerful tool for ensuring text legibility, it does have some major limitations:

Solutions: While a great convenience tool, any time the background is going to be a blue or a color with between 40-60% luminance, you must visually check the result and see how it actually looks. And if you need text to appear over images or gradient colors, or if you need colored text, you must still set those manually. None of these limitations make the function useless, but instead means this is a great tool for your toolkit - a tool that will get better over time - but it not a complete solution.