I’ve recently been working on a XUL application, and needed to fade gracefully from one colour to another. One of the stumbling blocks was trying to work out what my start and end colours actually are – or more to the point, provide some flexibility in specifying them. Ideally I wanted to allow all the colour definitions that are allowed in CSS (at least those that are allowed in Firefox 3 – the target environment for this application). That means allowing the following definitions for the colour white, for example:
white
#ffffff
#fff
rgb(255, 255, 255)
rgba(255, 255, 255, 1.0)
rgb(100%, 100%, 100%)
rgba(100%, 100%, 100%, 1.0)
hsl(0, 0%, 100%)
hsla(0, 0%, 100%, 1.0)
… plus a few variations to allow for different whitespace and so on.
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.
I decided to approach the problem in a different way – I’d let the browser do the hard work. It already knows how to deal with CSS colour names, and all the various other quirks of CSS colours, so why not use that to my advantage. Why not try to parse a few common colour definitions, but get the browser to parse the rest?
The result of this insight is linked below. It implicitly understands the “transparent” keyword (which it treats as white with an opacity of 0), as well as decimal rgb() and rgba() values. If you pass anything else to it, it creates a temporary document, inserts an HTML DIV, sets the DIV’s style.color attribute to the value you passed, then tries to read it back again using window.getComputedStyle(). The colorToRGBA() function is then called again using this computed colour as its parameter – and because (in Firefox) that value is a decimal rgb() or rgba() value, the function returns the four channels back to the caller. Neat, eh?
Note that it’s been coded specifically for Firefox 3 and hasn’t been tested on anything else. It makes assumptions about the way in which colours are returned from window.getComputedStyle() which would prevent it working as-is on any browser which doesn’t return the values as a decimal rgb() or rgba() string. It’s also limited to whatever CSS the browser itself understands. Finally it returns multiple values at once – a Javascript 1.7 addition called a “Destructuring Assignment” – though it could easily be modified to return a single array instead.
All of which is a long-winded way to say that this is an example of an idea for you to build on and run with, and definitely isn’t going to work across browsers without some extra work.
If all that still hasn’t put you off, you can find the code here: colorToRGBA.js
And some examples as to its use:
var R, G, B, A;
[R, G, B, A] = colorToRGBA("khaki");
// Returns [240, 230, 140, 1]
var R, G, B, A;
[R, G, B, A] = colorToRGBA("#ddfecd");
// Returns [221, 254, 205, 1]
var R, G, B, A;
[R, G, B, A] = colorToRGBA("#fcf");
// Returns [255, 204, 255, 1]
var R, G, B, A;
[R, G, B, A] = colorToRGBA("TRANSpareNT");
// Returns [255, 255, 255, 0]
var R, G, B, A;
[R, G, B, A] = colorToRGBA("hsla(120,50%,50%,0.5)");
// Returns [63, 191, 63, 0.5]