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()andtoRGB() - 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

February 23rd, 2006 at 4:37 am
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).
February 23rd, 2006 at 6:53 am
Excellent work! Will come in handy.
February 24th, 2006 at 12:25 am
Thanks, guys!
Baldo, I’ve added a
return false;onsubmit, so it’s not reloading the page. Thanks!February 25th, 2006 at 6:38 am
onsubmit of the form should be something like:
isThatAColor(document.getElementById(’colorinput’).value;)
so if you press enter, the color will be parsed!
February 25th, 2006 at 9:42 pm
Thanks, Baldo, the thing is that I was just being lazy and calling the parser
onblurignoring theonsubmit. Now I changed to theonsubmitto: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/idreturn false;- to not submit the form after the call to the parserThanks for the heads-up!
March 12th, 2006 at 11:39 pm
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!!!!
March 14th, 2006 at 1:11 am
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.
March 31st, 2006 at 11:56 am
[...] 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. [...]
April 4th, 2006 at 9:33 am
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
April 4th, 2006 at 9:35 am
April 4th, 2006 at 9:42 am
*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
April 4th, 2006 at 6:13 pm
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
April 5th, 2006 at 10:01 pm
Thanks for all your comments, Carl. I appreciate it.
April 12th, 2006 at 7:30 pm
Thanks a lot. Very useful script.
April 12th, 2006 at 8:18 pm
I’ve just added:
if (color_string == null)
color_string = “”;
after:
this.ok = false;
Cheers
April 17th, 2006 at 12:30 pm
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
May 27th, 2006 at 5:58 pm
Great job guys… Thank for you work…
July 6th, 2006 at 6:04 pm
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.
August 18th, 2006 at 1:31 am
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
August 18th, 2006 at 7:48 am
Thanks, Robert!
September 23rd, 2006 at 3:31 pm
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
October 18th, 2006 at 10:35 pm
The values are clipped in CSS3:
http://www.w3.org/TR/css3-color/#rgb-color
December 12th, 2006 at 7:16 am
Wow This class is very good.
December 15th, 2006 at 10:07 am
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
January 3rd, 2007 at 7:39 am
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
May 18th, 2007 at 12:22 am
Very useful !
Thanks !
August 22nd, 2007 at 5:28 am
Good work!
I’m using this for a website I launched this weekend at http://www.poundcolor.com.
Thanks again!
September 4th, 2007 at 4:55 pm
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!
September 19th, 2007 at 4:47 pm
[...] This javascript library solves the problem. http://www.phpied.com/rgb-color-parser-in-javascript/ [...]
September 20th, 2007 at 11:13 am
[...] use rgb color parser [...]
February 12th, 2008 at 11:49 am
pleas would you tell me how i can get pixel color in javascript ?and thank you verymuch…
May 23rd, 2008 at 4:11 am
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?
June 16th, 2008 at 7:56 am
Rgex expression for color for RGB format
June 22nd, 2008 at 3:04 am
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.
July 30th, 2008 at 10:31 am
[...] 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. [...]
July 30th, 2008 at 10:55 am
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.
August 4th, 2008 at 6:43 pm
Thanks for this… I rewrote it in python to use server-side: http://gregdingle.com/code/rgbcolor.py.txt .
August 4th, 2008 at 7:01 pm
Cool, thanks for sharing Greg!
September 11th, 2008 at 1:35 pm
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…
September 11th, 2008 at 1:41 pm
Ha oops I just noticed someone else (another Robert, no less!) said the same thing. Sorry for the redundancy.
December 30th, 2008 at 2:01 pm
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
January 22nd, 2009 at 12:26 am
[...] 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/ [...]
July 31st, 2009 at 6:11 pm
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.