Codename Rainbows

White Paper

How it All Works

Codename Rainbows allows you to effortlessly apply gradients, shadows and highlights to text. While that has been done extensively over the years, it had always required the use of images—which is especially problematic for dynamic content or large sites where hundreds of images could be required. View Demo.

The Schematic

A picture is worth a thousand words—so save yourself the trouble
Codename Rainbows Schematic: Many thin slices of slightly varying color text

Our Vision

Why we created Rainbows

We wanted a simple solution for dynamic gradiented headings.

Images look great, but you have to create everything by hand. Even with celeritous Photoshop skills, you'd need to spend lots of time on the tedious task of making every image. Time that could be used for the better things in life.

So we came up with an idea—What if we had a client-side script that would swoop in and beautify the titles for you? All you would have to do is create the HTML code, and you'd be set. No more messing about with Photoshop! You can spend all the extra time you now suddenly have relaxing on the beach, sipping a margarita.

Figure 1

Bullspot.com

The gradients and highlights on all the headers are created by a set of sprites with a unique image for each one.


While we like how this looks, it's a pain to manage. And thus Rainbows was born...

Bullspot.com site with image headers

The Markup

HTML + Javascript

The markup for Rainbows is surprisingly simple. Since the purpose of the script is to do away with an arduous task, we simplified as much as we could. The only code you need to add is to the head of your document.

For the <head>, you need to include the Rainbows script, as well as a line of your own that tells Rainbows where to apply. You can use an #ID or a .class selector, and you can make as many rainbows as you require.

	TODO: What path to the scripts?
	
<script src="jquery.js" type="text/javascript"></script>
<script src="rainbows.js" type="text/javascript"></script>

<script type="text/javascript">
	rainbows.init({
		selector: '.rainbows',

		gradient: true,
		from: '#ffffff',
		to: '#000000',
				
		shadow: true,
		highlight: true
	});
</script>

Figure 2

Dragon Interactive

Rainbows running in the header of Dragon Interactive.

A  header on Dragon Interactive

How it Works

Unweaving the rainbow

For those of you interested in what goes on White Paper, this section will explain how exactly Rainbows creates its dynamic gradients. I am assuming a basic knowledge of Javascript and jQuery, and will describe how Rainbows achieves its effect.

The gradient is actually comprised of a series of one-pixel-high slices of text. These slices are arranged vertically. Every slice is a slightly different shade, and when the slices are positioned via CSS the result is a smooth gradient created entirely without images.

Rainbows Revealed

Web colours are represented in HTML by hex codes: #RRGGBB. Rainbows takes the start and end colours and then interpolates them. Interpolation is the process of figuring out the colours in between: these are the colours that the gradient will contain.

The first ting to do before we can find the intermediary colours is to split up the colours into their chromatic triplets of red, green and blue. Since an HTML colour-code is just a set of three numbers in hex (base 16), it is just a matter of parsing the string and extracting the values (0-255) for each one. [code for that here]

Now that we have the starting and ending colours in RGB format, we can move on to the fun part. This is where interpolation comes in.

Interpolation

Interpolating colours is easy—we just need to calculate the intermediate colour values by "averaging" the red, green, and blue. We do this separately for each component colour. P is the percentage of the first colour (p = 1 - (h - i) / h), and it decreases every time loop through and get nearer to the end color.

R = startColour.R * p + endColour.R * (1 - p)
G = startColour.G * p + endColour.G * (1 - p)
B = startColour.B * p + endColour.B * (1 - p)
	

We loop h times (the height of the text), and the ratio of the colours on each iteration is given by p. Each loop-through brings us closer to the bottom of the text, and as the slice gets closer to the end, the slice-colour gets closer to being a pure shade of the end colour.

Slices of a Rainbow

The other side of Rainbows is the CSS for getting the slices to line up properly. The fact that they line up is what keeps the text looking like the original text.

So how did we accomplish this? With a little bit of lateral thinking. Every slice is a the full text, wrapped in a span, which is inside of another span:

<span class="rainbow rainbow-10" style="color: rgb(15,15,15);"><span style="top: -10px;">Rainbows</span></span>

The outer span is one pixel tall, and the inner span is moved around inside it. The outside span is like a window. The inner span moves to adjust what slice of the text is visible. Since this is the 10th slice in the example, the inner span is moved up ten pixels, exposing the appropriate portion of the text.

And that's how Rainbows works. The original text is split up into many pixel-high slices, and each one of these slices is individually coloured and positioned. And when we're done, these text-fragments combine into a simple, clean gradient.

Known Bugs

Even we're not perfect

Resizing in Safari 4 fails, for some odd reason. It seems to be preserving the height of the gradient text across different sizes. The highlights and shadows scale normally, though. By default it overshoots the slices a bit to give it room to grow at least one value. The height and effect is recalculated on load so just browsing at any set size should work like a charm, however.

Wrapping

Not exactly a bug, but it treats the text as one big block. So if it spans multiple lines that doesn't affect how it works at all. A possible fix for this is to change the color interpolation to loop based on how many lines there are. Generally it's used on things that are one line so we don't see it as that big of an issue. It really shouldn't be used on a whole paragraph or something...

Our favorite browser

IE6 has issues with 100% width in non-explicitly-sized containers (anything besides an actual pixel value). Running this in a fixed pixel width container will be fine, but try floating it or as a percentage and you will be disappointed. Not our fault really, but something to be aware of. This means it's a bit problematic inside floats, and you might have to feed IE a fixed pixel value for the parent.

Conclusion

At the end of the rainbow

That's all, folks! We hope you enjoy the script and use it to spruce up your site. If this article or script was helpful to you, join the discussion and let us know. We value all suggestions and comments.

Dragon Labs

Demonstration

See the script in action with some assorted examples.

Manual

Learn how to set up rainbows on your own site with just a few simple steps.

Download

Version 1.2
MIT License.

View Comments

Join the Discussion!

Follow us on twitter: @dragonlabs