Update March 4th, 2021: Modern browser support is really good, so couple of lines of CSS is enough!
Just few lines of CSS and you're done! No need for javascript to achieve the amazing rainbow text effect!
Add the following CSS: (LR stands for left-right and TD for top down)
.rainbow-lr {
background: linear-gradient(to right, red, orange , yellow, green, cyan, blue, violet);
color:transparent;
background-clip: text;
}
.rainbow-td {
background: linear-gradient(to bottom, red, orange , yellow, green, cyan, blue, violet);
color:transparent;
background-clip: text;
}
Sample HTML:
<div>
<span class="rainbow-lr">Rainbow text</span>
</div>
<div>
<span class="rainbow-td">Rainbow text</span>
<div>
This will show up as follows:
That's it!
This part is the old-old way from the times when Internet Explorer and friends were a thing...
In this post I introduce three ways to create rainbow texts for web.
Almost any image editor is capable of creating Rainbow Text. Gimp, Pixelmator, Photoshop - maybe anything except MS Paint. Just create a text and apply gradient for it. The exact way to achieve this varies depending on application you use, so I won't be going into details here. Basically you create image and use it:
<img src="rainbowtext.png" />
However, this way has two big problems: the text won't be searchable and the text will be difficult to change.
In other words, we should avoid this way.
More straightforward way is to create the text with separate elements. It means wrapping each letter in it's own element.
<span style="color: #f00;">R</span>
<span style="color: #f50;">a</span>
<span style="color: #ff0;">i</span>
<span style="color: #5f0;">n</span>
...
<span style="color: #f00;">R</span><span style="color: #f50;">a</span><span style="color: #ff0;">i</span><span style="color: #5f0;">n</span>...
As you can see, it's definitely NOT meant to be done manually. Basically you need to write some javascript to generate the codes. We'll take a look into that later.
The best way I have found is with CSS, because text will be easy to read and modify after you hide the style to .css file. This way includes creating a gradient that we use as background, and then clipping mask with text that shows background only where text is present.
.rainbow {
background-image: -webkit-gradient( linear, left top, right top, color-stop(0, #f22), color-stop(0.15, #f2f), color-stop(0.3, #22f), color-stop(0.45, #2ff), color-stop(0.6, #2f2),color-stop(0.75, #2f2), color-stop(0.9, #ff2), color-stop(1, #f22) );
background-image: gradient( linear, left top, right top, color-stop(0, #f22), color-stop(0.15, #f2f), color-stop(0.3, #22f), color-stop(0.45, #2ff), color-stop(0.6, #2f2),color-stop(0.75, #2f2), color-stop(0.9, #ff2), color-stop(1, #f22) );
color:transparent;
-webkit-background-clip: text;
background-clip: text;
}
With above text we can do:
Rainbows are colorful and scalable and lovely
Rainbows are colorful and scalable and lovely
This method works without JavaScript and is the cleanest solution because it's just few simple lines of CSS.
Note: If you use this in any other than display:inline element (such as span), it will spread the spectrum across the whole width, which may make it not making it not so rainbowish. For example:
Not rainbow!
Not rainbow!
You can get around this with span element:
Colorful rainbow.
Colorful rainbow.
However, even this way is not perfect, and there's one there's this one weak point: Older browsers do not support it! More information here
Since we need this to run perfectly in all browsers, we need...
In other words, use CSS if browser supports it, or use JavaScript if not.
This means using both methods, 2 and 3.
So here's how to achieve it. First we need JavaScript to to get the colors.
function color_from_hue(hue)
{
var h = hue/60;
var c = 255;
var x = (1 - Math.abs(h%2 - 1))*255;
var color;
var i = Math.floor(h);
if (i == 0) color = rgb_to_hex(c, x, 0);
else if (i == 1) color = rgb_to_hex(x, c, 0);
else if (i == 2) color = rgb_to_hex(0, c, x);
else if (i == 3) color = rgb_to_hex(0, x, c);
else if (i == 4) color = rgb_to_hex(x, 0, c);
else color = rgb_to_hex(c, 0, x);
return color;
}
function rgb_to_hex(red, green, blue)
{
var h = ((red << 16) | (green << 8) | (blue)).toString(16);
// add the beginning zeros
while (h.length < 6) h = '0' + h;
return '#' + h;
}
This has some mysterious looking HSL conversion math behind it. If you are interested about the details, check what Wikipedia says about converting HSL to RGB.
Next, we can wrap this into jQuery to make it easy to use.
(function( $ ) {
$.fn.rainbowize = function() {
return this.each(function() {
var rainbowtext = '';
var hue=0;
var step=0;
// get the current text inside element
var text = $(this).text();
// hue is 360 degrees
if (text.length > 0)
step = 360 / (text.length);
// iterate the whole 360 degrees
for (var i = 0; i < text.length; i++)
{
rainbowtext = rainbowtext + '' + text.charAt(i) + '';
hue += step;
}
$(this).html(rainbowtext);
});
};
})( jQuery );
Then to the CSS, we add rainbowize class for webkit browsers.
.rainbowize {
background-image: -webkit-gradient( linear, left top, right top, color-stop(0, #f22), color-stop(0.15, #f2f), color-stop(0.3, #22f), color-stop(0.45, #2ff), color-stop(0.6, #2f2),color-stop(0.75, #2f2), color-stop(0.9, #ff2), color-stop(1, #f22) );
background-image: gradient( linear, left top, right top, color-stop(0, #f22), color-stop(0.15, #f2f), color-stop(0.3, #22f), color-stop(0.45, #2ff), color-stop(0.6, #2f2),color-stop(0.75, #2f2), color-stop(0.9, #ff2), color-stop(1, #f22) );
color:transparent;
-webkit-background-clip: text;
background-clip: text;
}
Old versions of jQuery contained checks for browser support, such as webkit or firefox, but even then you could never be sure if the browser supports it. To detect if the browser support is available, we need to use Modernizr.
You can download the latest version from here: http://www.modernizr.com/downloads/modernizr-latest.js.
Then include it into your page.
However, modernizr does not contain test for background-clip by default, so you should add one:
Modernizr.addTest('backgroundclip',function() {
var div = document.createElement('div');
if ('backgroundClip' in div.style)
return true;
'Webkit Moz O ms Khtml'.replace(/([A-Za-z]*)/g,function(val) {
if (val+'BackgroundClip' in div.style) return true;
});
});
Basically this means, that if the support exists, it will add "backgroundclip" class for the html element. Finally we connect everything to document's ready function.
$(document).ready(function() {
if( !$("html").hasClass("backgroundclip") )
$(".rainbow").addClass("rainbowize");
else
$(".rainbow").rainbowize();
});
Now, whenever you write something like
I love rainbows because they are so colorful!
it will show up as "I love rainbows because they are so colorful!" and will look like rainbow in any browser.