How to Determine Font Color based on a Random Background Color
Tags: javascript, tutorial, webdev
Published: 2020-10-30 20:30:22

Inspired by [this great post](https://dev.to/dailydevtips1/vanilla-javascript-random-colours-2nnp) 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](https://convertingcolors.com/decimal-color-16777215.html) (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](https://www.w3.org/TR/AERT/#color-contrast). 

> 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()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/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:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/rjmoyle1wqi63eudnpw9.gif)