Make Rainbow-Colored Lists (and other HTML elements) – jQuery plugin
How to make rainbow-colored lists? I started searching for a solution and found a plugin for rainbow text, which inspired me to write my own jQuery plugin to rainbow-ify lists and other sets of HTML elements.
I’m used to working with RGB hex color codes. But there is no intuitive way to generate a spectrum of color using RGB, so I turned to HSL (hue, saturation and lightness). Most modern browsers support colors specified with hsl(hue, saturation%, lightness%), although IE versions prior to 9 do not. So I started out using HSL, adding IE support later. I found that keeping the saturation and lightness constant at 100% and 80% respectively while increasing the hue in steps produces a really nice rainbow effect.
Let’s back up a bit. Consider the following styled list:
I’d like to color this list to look like a rainbow. Using CSS alone is unwieldy; without knowing in advance the number of elements in the list, it’s impossible. We need to use Javascript to get this result:
Here’s how I did it–my rainbow plugin code (~1KB when minified):
(function($) {
'use strict';
//the plugin function
$.rainbow = $.fn.rainbow = function(options) {
if (this.length !== 0) {
//initialize settings & vars
var settings = $.extend(
{ hueStart: 0,
selector: '> *',
saturation: 100,
lightness: 80,
rgb: true },
options),
$rainbowed = this,
//ensure values are within proper range
hstart = ensure(settings.hueStart, 0, Number.MAX_VALUE) % 360,
sat = ensure(settings.saturation, 0, 100),
light = ensure(settings.lightness, 0, 100);
return $rainbowed.each(function() {
var $selected = $(this).find(settings.selector),
hue = hstart,
step = $selected.length === 0 ? 0 : 360 / ($selected.length);
// iterate over selected elements to colorize
$selected.each(function() {
if (!settings.rgb) {
$(this).css({'background-color': 'hsl('+ hue +', '+ sat +'%, '+ light +'%)',
'border-color': 'hsl('+ hue +', '+ (sat / 2) +'%, '+ (light / 2) +'%)'});
}
else {
$(this).css({'background-color': hslToRgb(hue, sat, light),
'border-color': hslToRgb(hue, sat / 2 , light / 2)});
}
hue += step;
});
});
}
};
function ensure(val, min, max) {
val = parseInt(val, 10);
if (isNaN(val) || val < min)
return min;
else if (val > max)
return max;
else
return val;
}
function hslToRgb(h, s, l) {
var r, g, b;
h = h / 360;
s = s / 100;
l = l / 100;
if (s === 0)
r = g = b = l; // achromatic
else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s,
p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return 'rgb('+ Math.round(r * 255) +','+ Math.round(g * 255) +','+ Math.round(b * 255) +')';
}
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
}
})(jQuery);
This plugin accepts several optional arguments:
- hueStart – a value from 0 to 360 representing the start of the rainbow, defaulted to 0 which is red.
- selector – a jQuery selector that grabs the set of elements to colorize, defaulted to “> *”, i.e. all children.
- saturation – a value from 0 to 100 representing the saturation percentage, defaulted to 100.
- lightness – a value from 0 to 100 representing the lightness percentage, defaulted to 80.
- rgb – a boolean value instructing the plugin to use CSS RGB syntax instead of HSL, defaulted to true.
Note that rgb = true requires some additional overhead to convert HSL to RGB, but is necessary if you are supporting IE versions prior to 9. Credit for the conversion function goes to Mohsen @ SO.
This is the HTML for the list:
<ul id="rainbowList"> <li>Java</li> <li>JavaScript</li> <li>PHP</li> <li>Python</li> <li>C#</li> <li>C++</li> <li>SQL</li> <li>Objective-C</li> <li>Visual Basic</li> <li>Ruby on Rails</li> <li>Scala</li> <li>jQuery</li> <li>HTML5</li> </ul>
The initial CSS:
#rainbowList { list-style: none; width: 270px; margin: 10px; }
#rainbowList li { background-color: #ddd;
border: 1px solid #999;
border-radius: 3px 3px 3px 3px;
color: #333;
padding: 3px 7px;
text-align: center;
text-decoration: none;
width: 200px;
font: bold 1em Georgia,serif;
margin: 6px; }
And calling the plugin to turn it from gray to rainbow:
$(document).ready(function() {
$('#rainbowList').rainbow();
});
Notice in this example I’m using all the plugin defaults. The rainbow colors are applied to the li tags. The number of rainbowized elements can be arbitrary; the plugin will step through the color spectrum with a finer or coarser grain depending on how many elements there are. Note as well that there is no requirement to use a list. Any HTML structure can be used.
The result here looks good, but it’s not quite good enough. Some CSS shadowing effects will make it pop, so I added this to the li’s style:
box-shadow: 1px 1px 1px 1px rgba(255, 255, 255, 0.5) inset,
-1px -1px 1px 0 rgba(0, 0, 0, 0.3) inset,
1px 1px 1px 1px rgba(33, 33, 33, 0.14);
text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.5);
That’s three box shadows for each li tag. The first adds a light inner shine from the upper left, the second adds a bit of an inner shadow on the bottom right, and the last adds a subtle drop shadow. I included a text shadow as well. This is the final result:
Try the demo to adjust the rainbow plugin settings and view the results. You can play around with the starting hue, the saturation and lightness.
I hope you find this plugin useful! Feel free to use it in your projects. A link back here is not required, but always appreciated!



