Frontend

Change Text Color in CSS based on Background

We will discover how to change text color in CSS based on background color in this article.

In projects, it is common to encounter scenarios where the background color is uncertain. In order to ensure that the content text is sufficiently clear and visible, there needs to be sufficient contrast between the text and the background. In other words, when the background is dark, as illustrated below:

In typical scenarios, it is common to calculate the grayscale of a background color using JavaScript. The algorithm for this calculation is well-known. If the RGB values of a color are known, the grayscale value can be obtained using the following method.

luma = (red * 0.2126 + green * 0.7152 + blue * 0.0722) / 255

This approach yields a range value between 0 and 1, allowing for the establishment of a threshold based on specific requirements. Values exceeding the threshold are classified as light colors, while those below are classified as dark colors.

Can pure CSS achieve the same effect? Absolutely, and it can be implemented even more easily. Let’s take a look together.

CSS Filter

<div class="box">
  <span class="text">Article</span>
</div>

Then, the container and text are represented in the same color, with the intention of establishing a visual association between the text color and the background.

.box {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 230px;
  height: 130px;
  font-size: 30px;
  
  color: #ffeb3b;
  background-color: currentColor;
}

How to convert colored text to black and white?

When it comes to black and white, one can utilize a grayscale filter to transform colored text into shades of gray.

.text {
  filter: grayscale(1);
}

The results are as follows:

However, in the current context, it is difficult to clearly perceive this shade of gray. What we need is pure black or white, but currently it is only gray. How can we enhance it? In this case, we can utilize a contrast filter to add an additional layer on top of the previous one.

.text {
  filter: grayscale(1) contrast(999);
}

Enhancing contrast results in a deeper black and a brighter white. Light gray shades are transformed into white, while dark gray shades are transformed into black.

The preceding procedure involves converting the original color through a filter to correspond with either white or black and ultimately requires the use of an invert filter to reverse the black and white.

.text {
  filter: grayscale(1) contrast(999) invert(1);
}

The process of conversion is represented below in a diagram:

Furthermore, the CSS working group is currently drafting a color contrast function called “color-contrast” that automatically selects the color with the highest contrast from a given set of colors. The implementation of this function is as follows.

.text-contrast-primary {
  color: color-contrast(var(--theme-primary) vs white, black);
}

Leave a Reply

Your email address will not be published. Required fields are marked *