Once upon a time, grayscale image has to be manually converted in order to be displayed on the web. Now with HTML5 canvas, images can be manipulated into grayscale without having to use image editing software. I've put together a demo to show you how to use HTML5 & jQuery to dynamically clone color images into grayscale (see demo). Credits: thanks to Darcy Clarke (my Themify's partner) for the jQuery and Javascript code.
The Purpose
This demo is intented to show you how to make a grayscale/color image hover effect with HTML5 and jQuery. To achieve this effect before HTML5, two images are required: a color and a grayscale version. Now HTML 5 made it easier and faster because the grayscale image is generated from the original source. I hope you will find this script useful in your design such as portfolio showcase, photo gallery, etc.
jQuery Code
The jQuery code below will look for the target images and generate a grayscale version. When hovering the image, it will fade the grayscale image into color.
<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
// On window load. This waits until images have loaded which is essential
$(window).load(function(){
// Fade in images so there isn't a color "pop" document load and then on window load
$(".item img").fadeIn(500);
// clone image
$('.item img').each(function(){
var el = $(this);
el.css({"position":"absolute"}).wrap("<div class='img_wrapper' style='display: inline-block'>").clone().addClass('img_grayscale').css({"position":"absolute","z-index":"998","opacity":"0"}).insertBefore(el).queue(function(){
var el = $(this);
el.parent().css({"width":this.width,"height":this.height});
el.dequeue();
});
this.src = grayscale(this.src);
});
// Fade image
$('.item img').mouseover(function(){
$(this).parent().find('img:first').stop().animate({opacity:1}, 1000);
})
$('.img_grayscale').mouseout(function(){
$(this).stop().animate({opacity:0}, 1000);
});
});
// Grayscale w canvas method
function grayscale(src){
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var imgObj = new Image();
imgObj.src = src;
canvas.width = imgObj.width;
canvas.height = imgObj.height;
ctx.drawImage(imgObj, 0, 0);
var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
for(var y = 0; y < imgPixels.height; y++){
for(var x = 0; x < imgPixels.width; x++){
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
return canvas.toDataURL();
}
</script>
How to use it
To apply this to your site:
- include a copy of jquery.js
- paste the code as shown above
- set the target image (eg:
.post-img,img,.gallery img, etc.) - you may change the animation speed (ie. 1000 = 1 second)

Compatibility
It works with any browser that support HTML5 and Javascript such as Chrome, Safari, and Firefox. If HTML5 is not supported, it will fallback to original color image. Note: if it doesn't work with Firefox and Chrome locally. You need to put the HTML file on a web server.
Credits
The Javascript & HTML 5 grayscale is coded by Darcy Clarke.

Cool effect, very useful scripts. thanks for sharing.
Looks awesome, and nice effect. One thing tho… I think the hover effect is a bit slow
Is there a link to the full HTML code?
This method is very slow… I do not recommend using
Sorry, but how exactly is this HTML5? It’s using an XHTML 1.0 Doctype rather than the HTML5 , nor are the meta or script tags marked up using HTML5 syntax. Likewise you’ve used divs rather than section tags etc. I’ve viewed this under Fx, Chrome, Safari etc. Are you using something server side to push it out as XHTML1.0 syntax? If not then you shouldn’t be pushing this out as an HTML5 tutorial.
this is great thank you… for much..
the demo is pretty good & also help me..
Thanks for post. keep it up
Great, I’ve been lookin’ for while some thing like this, thanks mate
This is just great. Saves a lot of time. Thanks!
Very nice and smooth effect !
great effect for photo galleries and even for bloggers.I found it very useful as i was designing a portfolio site so it helps with jquery scripting.
wow. Nice effect
Your can improve the speed and maintenance by using a var and/or jquery chaining.
If your call each time $(‘.item img’), jQuery have to find the selector each time. By putting it into a var you make jQuery select just once.
So…
var $imgToGrayify = $('.item img');
$imgToGrayify.fadeOut(500)
$imgToGrayify.each(function() {... })
$imgToGrayify.mouseover(function() {...});
Or doing this
var $imgToGrayify = $('.item img');
$imgToGrayify.fadeOut(500).each(function() {... }).mouseover(function() {...});
Or finally, this:
$('.item img').fadeOut(500).each(function() {... }).mouseover(function() {...});
Enjoy ;)
nice! will try out soon :-)
thanx for this tip
Could it be the other way around? from greyscale to color. So you get in color selected ones
Really a nice article!
This article should be renamed and it’s description amended as it is very misleading. I have looked a number of times at the example page and cannot find one piece of HTML5! wtf?
If I put the script on my website it will affect all images,right? There isnt a way of calling this effect just by an ‘id’? Because i would like to use floating image load, like you click the image, then open a window (inside the site) that shows the image…
I did found a way to express my self better. I wish compatibility with Lightbox JS.