RGB color parser in JavaScript

What is it

A JavaScript class that accepts a string and tries to figure out a valid color out of it. Some accepted inputs are for example:

  • rgb(0, 23, 255)
  • #336699
  • ffee66
  • fb0
  • red
  • darkblue
  • cadet blue

For more accepted inputs - see the demo.

Here's the javascript class - rgbcolor.js.

Some history / motivation

I was playing around with an idea (will post later) and I needed to get color information using the so-called computed styles. The thing is that I needed the exact amounts of Red, Green and Blue, so I needed to parse the value returned.

In FireFox when you get a computed style, it's in the format rgb(xxx, yyy, zzz)
In IE, it's #xxyyzz.
So I needed to parse both formats.

I decided to take my script one step further and make the color parsing into a seperate class. Then I added those string values - red, green, etc.

The result is something you can use, among other purposes, as a friendlier user input field.

How to use

The class is defied in a function RGBColor(). When you instantiate the class, you pass the string to be poarsed. The class has variables for the three channels - red, green and blue and methods to get the parsed value - toHex() and toRGB().

Example use:

var color = new RGBColor('darkblue');
if (color.ok) { // 'ok' is true when the parsing was a success
    // alert channels
    alert(color.r + ', ' + color.g + ', ' + color.b);
    // alert HEX and RGB
    alert(color.toHex());
    alert(color.toRGB());
}

How it works

  • The class accepts a string
  • Any leading # is stripped; spaces are stripped
  • There' s a check against a list of valid color names, such as "red" and "darkorange" and these are mapped to a Hex code
  • An array of objects is defined that have one regexp property and a function that knows what to do if the regexp find a match
  • There is a quick validation that the channel values are between 0 and 255
  • The two getters are defined - toHex() and toRGB()
  • Finally there is a function that acts as both a self-documentation and self-uinttest, where a bunch of accepted values are automatically run through the class and parsed and the result is displayed as a help text.

The idea of the array of objects containing a regexp and a handler function is Simon Willison's. He did a script to parse dates, which I used and modified to work with time entries.

In my time parser I also introduced the idea of the self-documenting regexps and the help/test function which I'm reusing here again.

All yours

Feel free to use the code for your own color picker tool or whatever you feel like. If you let me know how you use it, that would be even greater. Meanwhile any other comments are highly appreciated.

And if I may rephrase a TV ad:
Allowing your users to enter the color "Dark Khaki" - priceless! ;)

This entry was posted on Thursday, February 23rd, 2006 and is filed under JavaScript. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.


Get notification for future posts: follow me on Twitter or subscribe to my RSS feed

60 Responses to “RGB color parser in JavaScript”

  1. baldo Says:

    wow… great demo!

    p.s. there is a bug on firefox when i enter the color and press ENTER
    (the page reloads and looses the input value).

  2. Bramus! Says:

    Excellent work! Will come in handy.

  3. Stoyan Says:

    Thanks, guys!

    Baldo, I’ve added a return false; onsubmit, so it’s not reloading the page. Thanks!

  4. baldo Says:

    onsubmit of the form should be something like:

    isThatAColor(document.getElementById(‘colorinput’).value;)

    so if you press enter, the color will be parsed!

  5. Stoyan Says:

    Thanks, Baldo, the thing is that I was just being lazy and calling the parser onblur ignoring the onsubmit. Now I changed to the onsubmit to:

    onsubmit="isThatAColor(this.elements[0].value);return false;"

    this.elements[0].value – because again I was too lazy to give the input a proper name/id
    return false; – to not submit the form after the call to the parser

    Thanks for the heads-up!

  6. Cole Mickens Says:

    Wow. I was writing a cross browser color-fader-thing and I wrote my entire RGB->HEX->RGB object and this would have been much easier!!!!

  7. Stoyan Says:

    Hi Cole, thanks!

    You can check the lighter version of the parser, basically without the debug stuff and without the list of named colors (khaki et al). It’s in this posting, here’s the JS

    For the color fading, I tried this once for this project, but I had the luxury of always expecting colors as HEX #aabbcc. Here’s the code if you’re curious.

    Send me a link to your implementation when you’re ready, if you don’t mind.

  8. phpied.com » Blog Archive » The Focus and The Pocus Says:

    [...] Then getting the color value back is the tricky part (as I’m writing this I just thought I could simply store it once it’s generated, duh!). So I’m using my little RGBColor library (described here) in its lightweight version (also used here) to parse the value returned by getComputedStyle() a.k.a. currentStyle in IE. [...]

  9. Carl Says:

    Hi Stoyan!

    Impressive code! *very neat and well-coded!*

    A couple of questions, though:
    What’s up with that check you do for this.r, this.g, and this.b? Example:
    this.r = (this.r 255) ? 255 : this.r);
    Personally, I would think that leaving this part out would be better. As I see it, the values can never be

  10. Carl Says:
  11. Carl Says:

    *Oops, I see my use of less than / greater than tags messed up the post – I’ll use HTML entities instead*

    Hi Stoyan!

    Impressive code! *very neat and well-coded!*

    A couple of questions, though:
    What’s up with that check you do for this.r, this.g, and this.b? Example:
    this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);
    Personally, I would think that leaving this part out would be better. As I see it, the values can never be < 0 (if someone enters a negative value, this.r, this.g, and this.b will all be undefined and this.ok will remain false). Also, if the users inputs GGG as the color (leaving r g and b defined as NaN) and one wanted to allow this, wouldn’t it be closer to change this to 255, 255, 255 instead of 0, 0, 0?
    Myself, I just commented out that “value cleanup”, so now it doesn’t allow values such as GGG or rgb(333, 1, 4).

    Two more, minor things:
    In the loops running through “simple_colors” and “color_defs”, you could add a “break” so the loop stops executing when it’s found its match.
    If you move up the white space-stripper BEFORE the check for “#”, you would also allow the user to accidentally add a space before the “#” character.

    These are all minor adjustments, though. All in all – this has got to be one of the best scripts I’ve seen *and I’ve seen a lot :-) *! Well done! Thank you very much for allowing other people to play with your script!

    Sincerely,
    Carl

  12. Carl Says:

    Addition:
    I see now that I do need to do some validation, because I don’t want to allow for example:
    “greene”
    or
    “rgb(10, 999, 10)”
    to be accepted as colors. *I see how one might choose to allow these values, with some adjustments perhaps – but my choice is to disallow them*

    So, the cleanup I use now is:
    if (isNaN(this.r) || isNaN(this.g) || isNaN(this.b) || this.r>255 || this.g>255 || this.b>255) this.ok = false;

    Also, I didn’t want to allow for example:
    “#abcdefa”
    so I changed the substring call:
    if (color_string.charAt(0) == ‘#’) { // remove # if any
    color_string = color_string.substr(1);
    }

    Anyway, I just thought I’d leave a little note about the minor modifications I made, in case anyone else would like to try them. It’s just a matter of taste, I guess – what one wants to allow as input…

    Thanks again for the great script!

    /Carl

  13. Stoyan Says:

    Thanks for all your comments, Carl. I appreciate it.

  14. Bas Says:

    Thanks a lot. Very useful script.

  15. Bas Says:

    I’ve just added:

    if (color_string == null)
    color_string = “”;

    after:
    this.ok = false;

    Cheers

  16. Tom Bruinsma Says:

    This has saved me countless hours of pain and helped me achieve my deadline. I came down to the wire and experienced browser incompatibility with the way the color was being returned in FireFox versus IE. Using this helped me get my code out on time!

    Thanks You!
    Tom Bruinsma

  17. orton Says:

    Great job guys… Thank for you work…

  18. Ben Says:

    Appreciate the module. From both a design and efficiency standpoint, the simple_colors hash and the “getter” functions should be implemented through the RGBColor prototype, i.e.

    RGBColor.prototype.simple_colors = {
    aliceblue: ‘f0f8ff’,

    }

    And best of all, they are trivial changes to make.

  19. robert Says:

    This is a simple obvious little change. Where you have this:

    for (var key in simple_colors) {
    if (color_string == key) {
    color_string = simple_colors[key];
    }
    }
    // emd of simple type-in colors

    This would be much better:
    if (simple_colors[color_string]) {
    color_string = simple_colors[color_string];
    }

    You don’t need the loop at all. It may make only a small difference
    to this particular script, but if you often use this technique
    (unnecessarily searching arrays to see if a key exists), you can make your scripts simpler and faster this easy.

    Thanks… this is just what I needed for an idea I wanted to try.
    robert

  20. Stoyan Says:

    Thanks, Robert!

  21. fyo Says:

    RGB colors are not clipped according to the CSS, so values above 255 ARE PERMITTED and should pass validation. It would therefore be unwise to disallow them in the code.

    Cf:

    http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/css.html#CSS-RGBColor

  22. minghong Says:

    The values are clipped in CSS3:
    http://www.w3.org/TR/css3-color/#rgb-color

  23. Tim Golding Says:

    Wow This class is very good. :-)

  24. Fan of Don Lapre Says:

    First of all my thanks to you, i have been searching for this script for a long time.. You made my Script….

    Fan of Don Lapre
    larisa@larisajoyreilly.com

  25. Alex Says:

    Hi,

    A nice implementation – thanks!

    As a suggestion, how about putting the ‘color_defs’ structure outside of the object/function to be initialised on startup as a global. Just a bit neater and faster perhaps?

    Cheers,

    Alex

  26. CodeBit.cn Says:

    Very useful !
    Thanks !

  27. Cody Says:

    Good work!

    I’m using this for a website I launched this weekend at http://www.poundcolor.com.

    Thanks again!

  28. raf Says:

    Great, great, great!

    I spent like 2 hours or sth trying to figure out what’s wrong with my code, just to find out Opera and Firefox returns it in different format, ehh browsers…

    Thanks for your work!

  29. Shunsuke Saruwatari » Blog Archives » [javascript] color compatibility of IE and Firefox Says:

    [...] This javascript library solves the problem. http://www.phpied.com/rgb-color-parser-in-javascript/ [...]

  30. Shunsuke Saruwatari » Blog Archives » [javascript] solve browser incompatibility Says:

    [...] use rgb color parser [...]

  31. ali Says:

    pleas would you tell me how i can get pixel color in javascript ?and thank you verymuch…

  32. Barcode Scanner Says:

    A nice implementation – thanks!

    As a suggestion, how about putting the ‘color_defs’ structure outside of the object/function to be initialised on startup as a global. Just a bit neater and faster perhaps?

  33. allen Says:

    Rgex expression for color for RGB format

  34. PlNG Says:

    This is just what I was looking for, as I plan to be capturing set values (often in color format) as a test.
    No offense, but as robust as this is, it’s still not complete.
    It needs RGB as percentage values, RGBA, HSL, HSLA, and those as percentage values.
    Also, running it through the Javascript Lint seems to help performance some. There are a few minor errors that it caught that mostly go unnoticed due to the very loose nature of Javascript.

  35. My Green Life » Blog Archive » colorToRGBA() Says:

    [...] I found numerous bits of code to convert between hex and decimal triplets, and one bit of code that tries to be more comprehensive. Even that code fails with hsl() and hsla() values, not to mention the fact that it’s a large chunk of code with a huge lookup table to handle the various colour names that could be used. [...]

  36. MarkC Says:

    An different approach to this problem is the one I’ve posted on my blog:

    http://www.peppertop.com/blog/?p=69

    The code was written specifically for a XUL application running on Firefox 3, and will need some significant effort to make it work cross-browser, but it might provide a good starting point for someone.

    It uses the browser itself to parse any colour definitions that it doesn’t understand, so it handles any CSS that the browser itself handles. In the case of Firefox 3 this means that even hsl() and hsla() formats work.

  37. greg Says:

    Thanks for this… I rewrote it in python to use server-side: http://gregdingle.com/code/rgbcolor.py.txt .

  38. Stoyan Says:

    Cool, thanks for sharing Greg!

  39. rob Says:

    Hi….nice stuff. One minor quibble: you do this…

    for (var key in simple_colors) {
    if (color_string == key) {
    color_string = simple_colors[key];
    }
    }

    when the thing is already a hash table, so you just look it up rather than iterating the list:

    var tmp = simple_colors[color_string]
    if (tmp)
    color_string = tmp;

    I know, computers are fast and bandwidth is cheap, but still… :)

  40. rob Says:

    Ha oops I just noticed someone else (another Robert, no less!) said the same thing. Sorry for the redundancy.

  41. Danny117 Says:

    Thank you I was having so much trouble with color compatibility with firefox and ie.
    I’m putting your script out as is into my color selector on my website

  42. Get background color from IE in rgb format? | keyongtech Says:

    [...] Re: Get background color from IE in rgb format? teresni wrote: > Thanks, but I don’t want to hardcode the rgb values in my code. I was > hoping for some attribute I could access or parameter I could pass to > an existing method that would return the current background color as an > rgb value rather than as the color name. I haven’t tried it, but you could look at http://www.phpied.com/rgb-color-parser-in-javascript/ [...]

  43. P Says:

    Where did you get your color list?
    You should use the color list at http://www.w3.org/TR/SVG/types.html#ColorKeywords

    Robert’s suggestion is very nice, it should be put in as it cuts the script time by 1/3.

  44. Piyush Soni Says:

    Exactly what I was looking for. Thanks a lot for sharing the code. I’m using it right away :)

  45. David Says:

    I’ve got a pretty good tool to convert hex to rgb and convert rgb to hex :)
    Pretty cool!
    David

  46. Piyush Soni Says:

    I actually also needed the reverse functionality of this. That is, to read the color in hex/rgb values and give the answer to the user in the form he understands.

    I did the necessary changes mentioned in the comments, added some colors names from the w3c page, and modified the script a bit to add a functionality to convert hex/rgb to simple color names as well – so the class is sort of complete now :) .

    It’s uploaded at this location for anyone to use:
    http://piyushsoni.com/scripts/rgbcolor.js

    Hope this helps someone out there. I can be reached at piyush_soni@yahoo.com if someone wants to criticize, or thank me.

    Thanks a lot again Stoyan for this great work !

  47. Kieran Says:

    I’m using this in conjunction with CvsGraphCtx. In IE it’s throws an error on this line:

    channels = processor(bits);

    This can be fixed with this:

    var channels = processor(bits);

    Strange error but I thought I’d share it.

  48. Juho Vepsäläinen Says:

    Thanks for the library! It worked mostly just fine for my purposes. I had to extend it a little bit. I also made “toHex” more robust. You can find enhanced version of “toHex” here:
    http://gist.github.com/474238

    Kieran: I think that’s due to the fact that variables are treated global by default. “channels” overrides some global CvsGraphCtx depends upon. As you mentioned, adding “var” there fixes the issue.

  49. Terry Says:

    Thanks for this. Javascript was changing the css color correctly in all my browsers except Opera. Being able to check the HEX and RGB values of the color has fixed the problem.

  50. pahan Says:

    As already mentioned, CSS 2.1 and 3 permits values more then 255 for color components, but also permits negative values and values specified in percents (255=100%) which too may be higher then 100%. So if somebody wants to have a strict CSS compliance, (s)he should modify this script accordingly.

  51. Will Fastie Says:

    Thank you for this very nice class. I’m using it with GelForm’s CrayonBox color picker (http://gelform.com/crayonbox-jquery-plugin/) to get the RGB values so I can calculate the gray value (.299R + .587G + .114B) and then choose a light or dark foreground color for the selection indicator. Very handy.

  52. Will Fastie Says:

    As an experiment, I added this method to the class:

    this.toGrayLevel = function () {
    return (this.r*299 + this.g*587 + this.b*114)/1000;
    }

    Seems to work.

  53. Colin Says:

    This is great! I definitely think the reverse is a very useful – and perhaps has a wider application of uses?

  54. Jane Silver Says:

    Thanks for schooling me on Javascript color parsers!

  55. Kenny Pantaleo Says:

    Hello may I quote some of the material from this site if I reference you with a link back to your site?

  56. giao diện Việt - giao dien website Says:

    Hi, Neat post. There’s a problem with your website in internet explorer, could test this? IE still is the marketplace leader and a large portion of people will omit your magnificent writing due to this problem.

  57. fita de leds Says:

    Hey very nice site!! Man .. Beautiful .. Wonderful .. I will bookmark your site and take the feeds additionally?I’m glad to seek out so many helpful information here within the put up, we want develop more techniques in this regard, thank you for sharing. . . . . .

  58. minecraft Says:

    minecraft…

    [...]RGB color parser in JavaScript / Stoyan’s phpied.com[...]…

  59. lds temple Says:

    lds temple…

    [...]RGB color parser in JavaScript / Stoyan’s phpied.com[...]…

  60. ebay gift card codes hack Says:

    ebay gift card codes hack…

    [...]RGB color parser in JavaScript / Stoyan’s phpied.com[...]…

Leave a Reply