Marian

Posted on

# How to Determine Font Color based on a Random Background Color

Inspired by this great post by @dailydevtips1 about how to create random colors with Vanilla Javascript, I decided to write a little follow-up to make sure, the random color also has a matching font-color.

## Creating the Random Background Color

As a reminder, we are generating random hexadecimal number with this function:

Math.floor(Math.random()*10000000).toString(16)

Actually, we might as well use 16777215 as a multiplier, which is the maximum possible decimal for a color (meaning 16777215 === #FFFFFF).

The result of this formula is a 6-digit hexadecimal number. Like RGB colors it consists of three parts:

• The first two digits represent the color red
• digits three and four represent the color green
• the last two digits represent the color blue

## Determining the Font Color

To determine, which is the best possible font-color for a certain background, we can follow the recommended algorithm on www.w3.org.

Color brightness is determined by the following formula:
((Red value X 299) + (Green value X 587) + (Blue value X 114)) / 1000

Converting this formula to Javascript could look something like this:

``````const red = parseInt(color.substring(0,2),16)
const green = parseInt(color.substring(2,4),16)
const blue = parseInt(color.substring(4,6),16)
const brightness = red*0.299 + green*0.587 + blue*0.114
``````

Now we have an integer value for the perceived brightness of our background color.

We took each color from the previously generated random color using `substring` and converted the hexadecimal to a decimal using `parseInt()`.

Since the variable `brightness` of our function represents the brightness of our color, we can now use it to define the font color. I found that 180 is a good threshold to switch from white to black, but it's probably best to experiment a bit.

The function to set the font color could look like this.

``````if (brightness > 180) {
return { backgroundColor: '#' + color }
}
else return {
backgroundColor: '#' + color,
color: '#ffffff'
}
``````

And my whole function looks like this:

``````  const randomColor = () => {
let color = Math.floor(Math.random()*16777215).toString(16)

/* sometimes the returned value does not have
* the 6 digits needed, so we do it again until
* it does
*/

while (color.length<6) {
color = Math.floor(Math.random()*16777215).toString(16)
}

let red = parseInt(color.substring(0,2),16)
let green = parseInt(color.substring(2,4),16)
let blue = parseInt(color.substring(4,6),16)
let brightness = red*0.299 + green*0.587 + blue*0.114

/* if (red*0.299 + green*0.587 + blue*0.114) > 180
* use #000000 else use #ffffff
*/

if (brightness > 180) {
return { backgroundColor: '#' + color }
}
else return {
backgroundColor: '#' + color,
color: '#ffffff'
}
}
``````

In an app it would look like this:

## Top comments (2)

Miguel Manjarres

Interesting, could this be used for, say, a website that lets the user dynamically choose the colors? (Primary and accent). Excellent post by the way!

Marian

I guess so. You just have to make sure that the color the user chooses can be split into red, green and blue. When using random colors I sometimes had 5 digits and the formula did not work, which is why I added the `when` loop.
Thanks! π