52

What is the best way to generate a random color in JavaScript Without using any frameworks...

Here are a couple of solutions I came up with:

function get_random_color() 
{
    var color = "";
    for(var i = 0; i < 3; i++) {
        var sub = Math.floor(Math.random() * 256).toString(16);
        color += (sub.length == 1 ? "0" + sub : sub);
    }
    return "#" + color;
}

function get_rand_color()
{
    var color = Math.floor(Math.random() * Math.pow(256, 3)).toString(16);
    while(color.length < 6) {
        color = "0" + color;
    }
    return "#" + color;
}

Are there better ways to do it?

hostingutilities.com
  • 8,894
  • 3
  • 41
  • 51
  • 7
    If you're generating colors for humans and need a large number of distinguishable colors you may be better off with random HSV (see http://en.wikipedia.org/wiki/HSL_and_HSV) values. Because you can provide fewer possibilities for S and V but still get colors that look different. – George Phillips Jul 20 '09 at 09:00
  • 1
    Possible duplicate of [Random color generator in JavaScript](http://stackoverflow.com/questions/1484506/random-color-generator-in-javascript) – Damjan Pavlica Apr 19 '17 at 09:54

10 Answers10

134

A shorter way:

'#'+(0x1000000+Math.random()*0xffffff).toString(16).substr(1,6)
Franck Freiburger
  • 26,310
  • 20
  • 70
  • 95
  • 1
    Very short solution indeed =) I would give you +1 but I can see this failing in the (admittedly very rare) cases that `Math.random` returns values like `0.0` or `0.5`. – Blixt Jul 20 '09 at 09:33
  • 1
    true, now it should be ok (and quite close your solution but shorter :) – Franck Freiburger Jul 20 '09 at 09:47
  • Yup, but now you've got the problem with having to pad the string with 0 (if result is `<= 0xFFFFF`) That's what I'm doing in the second statement. – Blixt Jul 20 '09 at 10:07
  • 1
    +1: Using the same style (i.e. space between operators etc.), your code is somewhere around 35 characters shorter =) Here's the formatted version of your code I used for comparison: `return '#' + (0x1000000 + Math.random() * 0xFFFFFF).toString(16).substr(1,6);` – Blixt Jul 20 '09 at 10:44
  • 1
    Soubok, would you mind me using your solution over at javascriptcookbook.com? A reader thought it would be a nice addition. – Raymond Camden Jul 06 '13 at 15:54
  • 1
    If you intend to generate obscene amounts of random colors (millions), flooring the number is up to an order of magnitude faster (because `toString` has to work much less with an integer): `'#' + (0x1000000 + Math.floor(Math.random() * 0x1000000)).toString(16).substr(1);` (note that the multiplication must be with `0x1000000` instead of `0xFFFFFF` because `Math.random` returns range `[0, 1)` – that is, it will never return `1.0`). https://jsperf.com/random-hex-color – Blixt Apr 20 '17 at 15:03
  • redundant parentheses around `(Math.random())` – Igor Sukharev Feb 13 '21 at 04:41
  • Thanks for the the answer. Since `substr` is deprecated, it will be great to replace it with `substring`. But note that the with `substring. – Eli Jan 02 '22 at 21:37
15

Here's a way to generate a random color and provide the minimum brightness:

function randomColor(brightness){
  function randomChannel(brightness){
    var r = 255-brightness;
    var n = 0|((Math.random() * r) + brightness);
    var s = n.toString(16);
    return (s.length==1) ? '0'+s : s;
  }
  return '#' + randomChannel(brightness) + randomChannel(brightness) + randomChannel(brightness);
}

Call randomColor with a value from 0-255, indicitating how bright the color should be. This is helpful for generating pastels, for example randomColor(220)

David Mihal
  • 944
  • 6
  • 23
  • 1
    This is the best code I have seen so far that works based on HSV.. Great work.. Use it if you want random light colors in your page.. Here is some further reading http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/ – Faiz Jun 03 '14 at 06:06
14

I like your second option, although it can be made a little bit simpler:

// Math.pow is slow, use constant instead.
var color = Math.floor(Math.random() * 16777216).toString(16);
// Avoid loops.
return '#000000'.slice(0, -color.length) + color;
Blixt
  • 49,547
  • 13
  • 120
  • 153
  • 1
    I don't think `substr` is deprecated, but it's less standard than `substring` and `slice`. It's worth noting that `substr` behaves differently from `substring` too. Anyways, I changed to `slice` because it makes the code simpler as an extra bonus. =) – Blixt Jul 20 '09 at 08:09
  • 2
    Or on one line: ```"#" + ("000000" + Math.floor(Math.random() * 16777216).toString(16)).substr(-6);``` – wronex Jun 08 '14 at 10:14
12

I did it like this, with the help of other answers:

'#' + parseInt(Math.random() * 0xffffff).toString(16)
Damjan Pavlica
  • 31,277
  • 10
  • 71
  • 76
  • `0.06029829654625929 => #f6fb5`, `0.01086451193560456 => #2c804`, `0.013915316490329177 => #38ff4`, `0.0421506948772119 => #aca63`, `0.0067180071741699265 => #1b845`, `0.02415522842446105 => #62f09`, `0.01397159804923187 => #393a4`, `0.01909063159540958 => #4e31f` – gaitat Jul 08 '20 at 14:13
  • #333 is the same colour as #333333 - this isn't trully random – Ruben Serrate Aug 23 '20 at 18:54
9

As George said the best way is to use HSL, so you can generate a bunch of random human-distinguishable colours. The similar idea is implemented in Adams Cole answer to the similar question, but his code have random color generator and hsl->hex rgb translator bundled together which makes it hard to understand and modify.

If you use one of the javascript color manipulation libraries (like jquery-color) color generation become trivial:

function rainbow() {
  // 30 random hues with step of 12 degrees
  var hue = Math.floor(Math.random() * 30) * 12;

  return $.Color({
    hue: hue,
    saturation: 0.9,
    lightness: 0.6,
    alpha: 1
  }).toHexString();
};
Community
  • 1
  • 1
Andrew
  • 8,330
  • 11
  • 45
  • 78
  • Is it possible to "add" another color and essentially have it pick up where it left off? For example, say you start with 30 items to color, but the user adds a 31st item. Is there a way to have it continue with its currently generated set and simply generate a 31st color that adheres to the prior hues and steps? – Spectator6 Dec 13 '18 at 20:45
6

More succinct:

function get_random_color2() 
{
    var r = function () { return Math.floor(Math.random()*256) };
    return "rgb(" + r() + "," + r() + "," + r() + ")";
}
Aaron Fi
  • 10,116
  • 13
  • 66
  • 91
  • 1
    You should define the function outside the `get_random_color2` function... Redefining a function for every call feels a bit unnecessary. The solution that was linked earlier was better, because it only called `Math.random` once, then used bit shifting to get the red/green/blue components. – Blixt Jul 20 '09 at 08:27
  • @Blixt here is what you talked about: `function randomRGB(){ var c = Math.random()*16777215; return 'rgb('+((c >> 16) & 0xff)+','+((c >> 8) & 0xff)+','+(c & 0xff)+')'; }` – George Oct 10 '17 at 21:05
4
function randomColor()
{
     color='rgb('+Math.round(Math.random()*255)+','+Math.round(Math.random()*255)+','+Math.round(Math.random()*255)+')';

     return color;
}

This returns a random RGB value.

3

This answer is the best method.

You should provide known colors to choose from instead of relying on purely numeric methods. You can use sites like ColorBrewer to choose color palettes that work well depending on the problem (qualitative dataset, quantitative, or whatever..)

['red','orange','yellow','green','blue','purple'][Math.random()*6|0]

var colors = {
  rainbow: ['red', 'orange', 'yellow', 'green', 'blue', 'purple'],
  qual: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f'],
  quant: ['#fff7ec', '#fee8c8', '#fdd49e', '#fdbb84', '#fc8d59', '#ef6548', '#d7301f', '#b30000', '#7f0000'],
  div: ['#67001f','#b2182b','#d6604d','#f4a582','#fddbc7','#f7f7f7','#d1e5f0','#92c5de','#4393c3','#2166ac','#053061']
};
randc = function(array) {
  return array[Math.random() * array.length | 0]
}
genc = function() {
  var frag = [];
  var arr = colors[$("select").val()];
  for (var i = 0; i < 1024; i++) {
    frag.push("<div style='background-color:" + randc(arr) + ";'></div>");
  }
  $("#demo").html(frag.join(''));
}
genc();
$("select").on("change", genc);
#demo {
  margin-top: 10px;
  font-size: 0;
}
#demo div {
  display: inline-block;
  width: 24px;
  height: 24px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
  <option value='qual'>Qualitative (categorical)</option>
  <option value='quant'>Quantitative (sequential)</option>
  <option value='div'>Divergent (republicans versus democrats)</option>
  <option value='rainbow'>Rainbow (my little pony)</option>
</select>
<div id='demo'></div>
nothingisnecessary
  • 6,099
  • 36
  • 60
1

Most succinct:

function get_random_color()
{
  return '#' + Math.random().toString(16).substring(4);
}

Nicolas Buduroi gave the above best code to get random color at Random Color generator in Javascript

Community
  • 1
  • 1
Jack Liu Shurui
  • 540
  • 1
  • 5
  • 14
  • 2
    This will return invalid colors often, the amount of decimal places Math.random() returns varies greatly. in FF it returns strings longer than 6 digits, and chrome/safari can go as low as 2 digits – bryc Nov 27 '12 at 18:10
1

I have created a slightly more complicated solution but one which lets you control the saturation of the colors and the brightness. You can check out the code for SwitchColors.js here https://github.com/akulmehta/SwitchColors.js

Coola
  • 2,934
  • 2
  • 19
  • 43