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.

Works beautifully on all browser except IE versions 7 8 and 9. Tough, but it would be nice if someone had a solution :)
What DOES work in any IE version? We should just stop supporting it. eventually MS will either comply with W3C or user will eventually see that things look like crap and other browser actually work.
Btw Awesome tutorial, Don’t mean to troll. but effects like these are awesome and that it wont work only in IE… Come on!
You actually can get it to work in IE 6 and up by using a ie’s grayscale filter.
Just replace
this.src = grayscale(this.src);With
if($.browser.msie){this.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayScale=1)';
} else {
this.src = grayscale(this.src);
}
Thanks for the fix. Worked perfectly for me.
thanks, that is a quick IE fix.
it works like a charm.
I’m sorry but it’s not really HTML5 it’s Javascript and jQuery put together with some HTML tags that were present since HTML 3
It is HTML5 as it generates a canvas grayscale image. How is that not HTML5?
I just wanted to construct a simple word in order to thank you for all of the precious facts you are showing at this site. My rather long internet research has now been honored with reliable information to share with my friends and classmates. I ‘d state that that many of us visitors actually are very much endowed to be in a really good community with very many outstanding professionals with great suggestions. I feel truly lucky to have encountered your website and look forward to really more fabulous times reading here. Thanks a lot again for all the details.
It’s easy to resent punctuation. Its purpose is to clarify sentences, so why are the rules governing it so complicated? There are so many exceptions, so many exceptions to exceptions — it’s enough to make you want forego punctuation altogether. Well, back when it was alive and kicking, the Latin language did just that — and it didn’t stop there. Written Latin also omitted spaces between words or lowercase letters.
And then he handed you the thirty-five 45
How could one reverse this effect = color to grayscale?
Well, it would be easiest to use 2 images, which is what this works around. I see no reason you couldn’t apply this in reverse… to have it switch from color to gray onMouseHover/Click, etc.
For instance, this:
// 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);
});
becomes this:
// Fade image
$(‘.item img’).mouseout(function(){
$(this).parent().find(‘img:first’).stop().animate({opacity:0}, 1000);
})
$(‘.img_grayscale’).mouseover(function(){
$(this).stop().animate({opacity:1}, 1000);
});
It would also have to be in color, rather than grayscale onLoad… I believe.
Where is html5?
Alexis Ohanian, co-founder of Reddit.com, talks about the value of college education and the “dire need” for skilled labor in the U.S. Higher education fails to provide students “good value” for the money they and their families spend, more than half of U.S. adults said in a Pew Research Center survey. Ohanian speaks on Bloomberg Television’s “InBusiness With Margaret Brennan.
ererer
Thanks , thats really an awesome post .
Nice Your Blog
Is it possible to use this in a fluid layout, when the images have to resize to 100% of their containing element?
I’m also looking for a solution for images set at 100% in a fluid layout. Does anyone have any ideas?
Where’s the HTML5, and why wouldn’t you rather do this server side?
I enjoy you because of each of your effort on this web page. Debby really likes carrying out investigations and it’s obvious why. My spouse and i hear all of the dynamic medium you give functional guidance by means of the blog and as well improve response from some other people on that situation then my child is now learning a lot. Take pleasure in the rest of the year. You’re the one doing a stunning job.
And then he handed you the thirty-five 55
How can I remove the grayscale when the image has been clicked? Still figuring this one out. :(
To set all images monochromatic use this:
$(‘img’).each(function(){
if ($.browser.msie) this.style.filter = ‘progid:DXImageTransform.Microsoft.BasicImage(grayScale=1)’
else {
var canvas = document.createElement(‘canvas’)
canvas.width = this.width
canvas.height = this.height
var ctx = canvas.getContext(’2d’)
ctx.drawImage(this,0,0)
var thisd = ctx.getImageData(0,0,this.width,this.height)
var pix = thisd.data
for (var i = 0, n = pix.length; i < n; i += 4) pix[i] = pix[i+1] = pix[i+2] = (pix[i] + pix[i+1] + pix[i+2]) / 3
ctx.putImageData(thisd, 0, 0)
this.src = canvas.toDataURL()
}
});
Need urgent help!!
1: On Hover on image it is converting to grayscale and on mouse out it reverts, but how to work around if you want whole div to be active (hover over anything in the div, like text or anything containing in the div) and the image shall animate.??
2: Images hosted in same directory are only working properly, but when images hosted on other site/domain are linked to img, its not working at all!
Hello!
Woww… I love this… and immediatelly I tried to use it for a test design: http://tarifakft.com/grayscale/
It works very nice, indeed!
However, there is a little “gap” at the left and the top of the images, where the cursor detects the other, next element. It does not follow the shape of the image, but uses a square…
How may I do it in a way, the the exact image is detected, and it senses the hover exactly over the appropriate image?
Thanks a lot!
Greetings,
Tamas
hi, sorry but I cant get it to work. i have followed the rules on putting the js in the head tag.
my gallery images are in a and I am putting
but its inside an anchor tag.
im I doing it right? giving the img a class name of “item img?” or where should I put it? I haven’t changed a coded in the JS.please help
Great
Thank you for sharing!!
its not working in chrome or firefox.. its only working in safari..
ret