DEV Community

Cover image for Vanilla JavaScript random colours
Chris Bongers
Chris Bongers

Posted on • Originally published at daily-dev-tips.com

Vanilla JavaScript random colours

Ever wondered how you can create random colours using Vanilla JavaScript?

The other day we made a JavaScript data-attribute filter, and I wanted to give each block a random colour.

So today we are going to do just that.

The end result will be as this Codepen (Open or reload to see random new colours)

JavaScript random hex colour

In our example, we will be generating a random hex number. These can be any six-characters from 0-9 and A-F.

Luckily in JavaScript, it's even easier to create a random hex string.

Let's break it down.

Math.random()*10000000
Enter fullscreen mode Exit fullscreen mode

This will give us a random number which will look like this:

2773929.134011086
9192315.941572387
Enter fullscreen mode Exit fullscreen mode

The next step is to floor this number to we will only get the first part.

Math.floor(Math.random()*10000000)
Enter fullscreen mode Exit fullscreen mode

Which would result in the following for the above examples:

2773929
9192315
Enter fullscreen mode Exit fullscreen mode

Now we need to create strings else we would only have numbers and one too many.

We can use the toString() method and specify the radix parameter as 16.

This will convert 254 to fe, for instance.

Math.floor(Math.random()*10000000).toString(16)
Enter fullscreen mode Exit fullscreen mode

This will get results like:

'2a53a9'
'8c437b'
Enter fullscreen mode Exit fullscreen mode

Awesome, Perfect hex values!

Random colour blocks in JavaScript

Now let's give our blocks all a random colour.

<ul>
  <li data-rating="4"><span>item 1</span><i>rating 4</i></li>
  <li data-rating="2"><span>item 2</span><i>rating 2</i></li>
  <li data-rating="3"><span>item 3</span><i>rating 3</i></li>
  <li data-rating="1"><span>item 4</span><i>rating 1</i></li>
  <li data-rating="4"><span>item 5</span><i>rating 4</i></li>
  <li data-rating="1"><span>item 6</span><i>rating 1</i></li>
  <li data-rating="4"><span>item 7</span><i>rating 4</i></li>
  <li data-rating="4"><span>item 8</span><i>rating 4</i></li>
  <li data-rating="1"><span>item 9</span><i>rating 1</i></li>
  <li data-rating="5"><span>item 10</span><i>rating 5</i></li>
  <li data-rating="1"><span>item 11</span><i>rating 1</i></li>
  <li data-rating="2"><span>item 12</span><i>rating 2</i></li>
  <li data-rating="3"><span>item 13</span><i>rating 3</i></li>
  <li data-rating="1"><span>item 14</span><i>rating 1</i></li>
  <li data-rating="3"><span>item 15</span><i>rating 3</i></li>
  <li data-rating="5"><span>item 16</span><i>rating 5</i></li>
  <li data-rating="3"><span>item 17</span><i>rating 3</i></li>
  <li data-rating="5"><span>item 18</span><i>rating 5</i></li>
  <li data-rating="1"><span>item 19</span><i>rating 1</i></li>
  <li data-rating="2"><span>item 20</span><i>rating 2</i></li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Now we need to get all our list items and loop over them.

const elements = document.querySelectorAll("li");

[...elements].forEach((element) => {
  element.style.backgroundColor = "#" + (Math.floor(Math.random() * 1e7).toString(16));
});
Enter fullscreen mode Exit fullscreen mode

It might not have the prettiest colours, but at least they're random!

You might have noted the 1e7 which is a shorthand Decimal Base Exponent.

It means one followed by seven zeroes.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Top comments (8)

Collapse
 
lionelrowe profile image
lionel-rowe • Edited

You'll get a more complete distribution throughout the RGB color space using 0x1_00_00_00 (decimal 16,777,216) as a multiplier, rather than 1e7 (decimal 10,000,000). Math.random is inclusive of the lower bound but not the upper bound, so Math.floor(Math.random() * 0x1_00_00_00) gives a number in the range 0x00_00_00..0xff_ff_ff (pure black to pure white). 1e7 - 1 (the maximum value with 1e7 as upper bound), on the other hand, converts to 0x98_96_7f, which is a sort of beige color.

I think that's why the colors you're generating are skewing toward greens and purples, bearing in mind that contiguous 6-digit hex numbers don't always look like similar colors, seeing as they're split into red-green-blue segments.

Collapse
 
lexlohr profile image
Alex Lohr • Edited

You'll still have a chance to hit a number low enough not to yield a 3- or 6-digit hex number, which will result in an invalid color (0x0-0xFF, 0x1000-0xfffff). To solve that, you can use

'#' + (0x1000000 + 0x1000000 * Math.random() | 0).toString(16).slice(-6)
Enter fullscreen mode Exit fullscreen mode

instead.

Collapse
 
lionelrowe profile image
lionel-rowe • Edited

Good point, forgot about that. A simpler fix would probably be hexStr.padStart(6, '0').

Collapse
 
dailydevtips1 profile image
Chris Bongers

Good point, it's not a failsafe method indeed thanks for this addition Lionel!

Collapse
 
hellnar profile image
Stas Klymenko

Hey, Chris!
I've actually made a few things with random colors both with hex and RGB. I think the RGB approach is a bit easier. Especially for newbies.
Here is a simple example:
codepen.io/Hellnar/pen/JjKMzzm

But anyway thanks for sharing your option. Also very nice and clean.

Collapse
 
dailydevtips1 profile image
Chris Bongers

True RGB(a) might be easier to understand for most people because it's easier to calculate with, nice one Stan!

Collapse
 
waylonwalker profile image
Waylon Walker

This looks like a super fun one. Very innovative and elegant solution 👍

Collapse
 
dailydevtips1 profile image
Chris Bongers

Thanks Waylon, as mentioned there are many ways of doing it in the comments as well.