Greyscale Hover Effect w/ CSS & jQuery
Tags: Intermediate
A few months ago, James Padolsey introduced a cool greyscale technique for non-IE browsers. His technique inspired me to come up with a workaround with a similar effect.
My solution relies on CSS Sprites and a few lines of jQuery, but requires a bit of preparation before it can be implemented. It is not recommended for large scale projects and probably best for displaying portfolio pieces.
Wireframe – HTML
First set up an unordered list which we will use as our foundation for the list
of gallery images.
<ul class="gallery"> <li> <a href="#" class="thumb"><span><img src="image.gif" alt="" /></span></a> <h2><a href="#">Image Name</a></h2> </li> </ul>
You will notice that each list will contain an image which is nested within a <span> tag. The <span> tag will be used to crop the image to only show its default state. Take a look at the image below to get a visual.

Styling – CSS
We will style this up as a typical gallery. Only thing unique about the below CSS is that we have the <span> to crop our image as we demonstrated in the above example.
ul.gallery {
width: 708px; /*--Adjust width according to your scenario--*/
list-style: none;
margin: 0; padding: 0;
}
ul.gallery li {
float: left;
margin: 10px; padding: 0;
text-align: center;
border: 1px solid #ccc;
-moz-border-radius: 3px; /*--CSS3 Rounded Corners--*/
-khtml-border-radius: 3px; /*--CSS3 Rounded Corners--*/
-webkit-border-radius: 3px; /*--CSS3 Rounded Corners--*/
display: inline; /*--Gimp Fix aka IE6 Fix - Fixes double margin bug--*/
}
ul.gallery li a.thumb {
width: 204px; /*--Width of image--*/
height: 182px; /*--Height of image--*/
padding: 5px;
border-bottom: 1px solid #ccc;
cursor: pointer;
}
ul.gallery li span { /*--Used to crop image--*/
width: 204px;
height: 182px;
overflow: hidden;
display: block;
}
ul.gallery li a.thumb:hover {
background: #333; /*--Hover effect for browser with js turned off--*/
}
ul.gallery li h2 {
font-size: 1em;
font-weight: normal;
text-transform: uppercase;
margin: 0; padding: 10px;
background: #f0f0f0;
border-top: 1px solid #fff; /*--Subtle bevel effect--*/
}
ul.gallery li a {text-decoration: none; color: #777; display: block;}
Step 3. Animation – jQuery
For those who are not familiar with jQuery, do check out their site first and get an overview of how it works. I’ve shared a few tricks that I have picked up along the way, you can check those out as well.
Initial Step – Call the jQuery file
You can choose to download the file from the jQuery site, or you can use this one hosted on Google.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
The logic here will be to fade out the default thumbnail, and set a background image on the <a> tag. Using CSS Sprites, we will position the image to the ‘bottom’ so the greyscaled thumbnail can seep through on hover over.
The following script contains comments explaining which jQuery actions are being performed.
jQuery
$(document).ready(function() { $("ul.gallery li").hover(function() { //On hover... var thumbOver = $(this).find("img").attr("src"); //Get image url and assign it to 'thumbOver' //Set a background image(thumbOver) on the <a> tag - Set position to bottom $(this).find("a.thumb").css({'background' : 'url(' + thumbOver + ') no-repeat center bottom'}); //Animate the image to 0 opacity (fade it out) $(this).find("span").stop().fadeTo('normal', 0 , function() { $(this).hide() //Hide the image after fade }); } , function() { //on hover out... //Fade the image to full opacity $(this).find("span").stop().fadeTo('normal', 1).show(); }); });
Conclusion
I’m sure there are various ways of achieving this technique. I decided to use CSS Sprites technique to prevent glitching on the initial hover over. If anyone has a better solution, have questions, or suggestions, please feel free to let me know!
Related Posts
Author Bio
My name is Soh Tanaka and I am a Los Angeles based designer/front-end developer specializing in CSS driven web design with an emphasis on usability and search engine optimization. I also run a CSS Gallery which is updated daily with the best CSS websites from around the world. Come check it out!
You can learn more about me or
Follow me on twitter for more updates and resources!
Did You Enjoy This Post?
Subscribe via RSS or by email to get all upcoming tutorials and articles delivered straight to you.





+ Add Comment107 Peeps Have Spoken Their Minds...
Hey Soh, I’ve to say, that it’s another great and useful article, You’ve made! I really like Your site, articles and tips! Keep in goin’ this way! :-)
wow, its gonna be useful for my portfolio I am designing.. :)
Thanks!
Great post and very nice looking effect.
realy nice hover effect. jquery and css rock.
I love the effect, really well done, Soh. Thumbs up!
Heh…it actually looks really good in reverse, too. Everything gray, then, when you hover, you get the color…
Jesse
Very nice example. I could definitly see myself using this. great job. and Jesse is right, could be used backwards. hmmm. maybe a variable for how you want it to start would be in order. start gray or color.
oooh, cool!
I totally agree with Jesse but I guess this technique makes it different to others, it’s not what you expect and I definitely like the transition :)
Thank you for posting this.
This is really great!
You got reason,is better for thumbs in galleries like exemple you bring us.
Thanks for sharing…Mr Tanaka.
@Jesse and the others…thought the same as I saw the demo first, but for this gallery the effect is nice as it is…I’ll maybe use it for the hover effec on the social-media-icons or something like that (but reversed) =)…great tutorial, thanks for this!!
It seems real hardwork to create a grayscale hover affect.
I would create an extra div wrapped around the image and then use z-index and hover pseudo-class. When the mouse hovered over the image I would create a 24 or 32 bit PNG to appear over the image. Alright so it wouldn’t work in IE6 but at least you don’t have to use that spawn of the devil commonly known as JavaScript.
Great stuff, and yea it would work great and reverse (:
@all thanks for the feedback~
Great suggestion for the reverse effect, I should also add that this is not only limited to color vs greyscale, but it can pretty much be any effect. It would be awesome to see some creative usage of this technique, I would love to check them out when you get them up and running :-)
@Andy yea you can do it that way, but the nice fade effect is what I like most about this technique. The sharp swaps of images would be a nice fall back option for those with js turned off. I would not call javascript the “spawn of the devil” though, just as long as your developing with graceful degradation in mind. Technology is changing fast and its now becoming a standard :-)
he Soh. you do good work – thanks.
your code art is always graceful, so i’m interested on your thoughts on not declaring the inline image height=”" and width=”" dimensions…? it’s not ideal for performance and semantics is it..?
is there a way around this, especially for those with A LOT of images..?
*** apologies. sometimes i ask really stoopid question (ie: the comment above).
of course “overflow: hidden;” is going to hide the overflow. so (of course) you can declare the img size attributes.
thanks again Soh.
Very useful. Thanks a lot!
Very GoOd!
Excelent!
Great stuff as always, Soh. Thanks for continuing to contribute to helping creative/tech folks stay in the know.
A very nice and helpful in did. Thanks for The sharing…
I am having a problem with the script, and I know it is probably something I am missing….but I would REALLY appreciate your help.
In IE it works great and looks just like your example, in Firefox the entire image fades to transparent instead of the bottom portion of the sprite.
———————
Script:
———————
$(document).ready(function() {
$(“ul.gallery li”).hover(function() { //On hover…
var thumbOver = $(this).find(“img”).attr(“src”); //Get image url and assign it to ‘thumbOver’
//Set a background image(thumbOver) on the <a> tag
$(this).find(“a.thumb”).css({‘background’ : ‘url(‘ + thumbOver + ‘) no-repeat center bottom’});
//Animate the image to 0 opacity (fade it out)
$(this).find(“span”).stop().animate({opacity: 0}, 300);
}
, function() { //on hover out…
//Animate the image back to 100% opacity (fade it back in)
$(this).find(“span”).stop().animate({opacity: 1}, 300);
})
});
———————
HTML:
———————
———————
CSS:
———————
ul.gallery {
width: 900px;
margin: 0 auto;
padding: 0;
clear: left;
}
ul.gallery li {
width: 171px;
height: 171px;
margin: 0 0 0 27px;
padding: 9px;
display: inline;
float: left;
border: 1px solid #ccc;
}
ul.gallery li span {
width: 171px;
height: 171px;
overflow: hidden;
display: block;
}
ul.gallery li a.thumb {
width: 171px;
height: 171px;
overflow: hidden;
cursor: pointer;
}
Any help you can give would be greatly appreciated and would help my sanity! :)
I spoke too soon. I figured it out. Something in my CSS wasn’t meshing well.
Thank you for the tutorial. It is amazing.
hey Soh, nice article man. ur tutorials r lot of help for beginners like me … keep it up.
Sweet work! :)
it does not work on chromium (webkit).
salU
very nice article … thanks for amazing tutorial …
SO COOL!!!!!
nice!!
very niace!!!!!!
I will use this technique for my site asap. Thanks.
HTML 5/CSS 3 should have filters for all of these cool effects
You can use background-position property:
$(this).find(“a.thumb”).css({‘background-position’ : ‘center bottom’});
Nice, I’m going to try and use this somewhere
I just implemented this effect. It looks awesome! What I’d really like to be able to do is swap these thumbnails for an enlarged version floating to the right of the thumbnail gallery with an onclick. Anyone now how to go about that?
Soh, Coool!
Twitter was involuntarily :-)
How is my English made?
Hi,
Nice tutorial. We’ve implemented something similar on our own site using PHP’s GDLib to automatically create grayscale images for us.
Check it out at:
http://www.deepbluesky.com/work/
Thanks for the nice tutorial.
Nice read, i’m going to be using this for on my next project.
Thanks for the article.
Benga creative
I just implemented this effect. It looks awesome! What I’d really like to be able to do is swap these thumbnails for an enlarged version floating to the right of the thumbnail gallery with an onclick. Anyone now how to go about that?
What do you mean by large scale projects? can you give us an example and why it is not recommended for that.
thanks
Hi Soh, thank you for sharing this excellent tutorial. It’s very useful. I’ve tried to use it on my website, but I just can’t get it done. jQuery is a quite new and difficult stuff for me. May I ask you for advice?
There is a background image in the li elements of a ul list on my website.
The thumbnail images in the a tags are much smaller than the background images of the li elements. That’s why I prefer the greyscale hover effect starts only when I’m reaching the thumbnail image but not when I’m reaching the background images of the li elements.
I hope You can help me!
Thank You in advance!
Another great tut, thanks!
nice tutorial! I like it!
It’s not working on Google Chromium : 4.0.221.7 (Ubuntu build 28103)
WOW! That really is a beautiful technique. I loved the way it just worked so nicely and looked really good. Thanks for this ;)
Very cool effect, thanks for the info!
Cant ignore it ..
thanks
How did you make that cool gradient effect for the second sprite? I can’t seem to make it work.
Anybody else notice that when you click on the “image” portion in IE 7, it doesn’t go anywhere? But if you click on the text below, it works. Everything works in Firefox.
Sounds like a glitch or something. =(
I’m trying to get the effect to be in reverse (black and white on load and color on hover) and am having some difficulty tweaking the code to do so. Can anyone point me into the right direction? I’m new to jquery. Thanks!
Would anyone be able to steer me in the right direction as to how I would be able to implement this on a WordPress Page. I’ve been trying for hours and for some reason can’t get this script to work…
The effect is very cool, but I think the script could be a bit better if you had used chaining. ;)
Thanks for this very nice and helpful tutorial. I appreciate and jquery very awesome :)
Really cool, I will use it on my next project!
Hi,
I have a thumbs who size Width:140px; Height:80px;
but in effet hover my pictures are not same size.. :(
Yes, this was very helpful. Thanks for the tut!
hi … has anyone tried this in reverse effect. i.e by default images will be faded and on hover original image is shown. i tried this but having issue in IE 8.
For those who are trying to reverse the effect, the easiest way is to just reverse the order on the images :-)
ただの画像にこのエフェクトを適用するにはどうしたらいいの?
太酷了!So Cool!
Waw, insane! I just discovered this website and it’s just great!
Thx for bringing webdesign to the next step!
this is great – is there anyway that when an image is hovered over, then when clicked it can open up a larger image in a lightbox style effect?
If you dont want to use css sprites this is far easyer:
$(“li”).hover(
function () {
$(“img”, this).fadeTo(“normal”, 0);
},
function () {
$(“img”, this).fadeTo(“normal”, 1);
}
);
This way you can use the effect for example in WordPress when you don’t always have the same image sizes.
hmm the comment ate my html^^. Lets try this:
<!– –>
<!– –>
<!– –>
Fuck I give up.
Just put your colored image in the list and make your greyscale image the background of your list tag.
great !
Quite good
I´d need some help with the start to make this on my site. On my slider i got on homepage. A frame and text under the picture,just like the one in the tutorial. Could anyone help me to start, and ill design something you need..
site is jemtee.com
Waw great tutorial, i will try it….keep posting bro…
Great Tutorial – but I’m having a huge issue with my images. Check it out, instead of greying my image becomes the background???
http://shocktheworldart.com/jquerytest.html
sweet effects.
For a similar, simpler and slightly less sexy effect, I have used reduced opacity for the a:hover in the past. Or you could use it for the a and have the a:hover at 100% opacity. Just a thought.
i really like this effect. any tips for us photoshop newbies on how to achieve that shadow effect on the grayscale image? i think that really adds to the effect. thanks :)
Hi there – I am new in CSS and Javascript but this was a very good- written explanation – thanks! I will use it on my site!
hey, great tutorial! Thanks so much for posting all this stuff. It’s really inspired me.
I started using your hover technique a while ago although I was finding that sometimes there was a delay before the bg-image would appear.
I re-developed it to solve that problem. If you wanna check out the code I posted it on my site http://beacon9.ca/labs/scripts/sexy-image-hover-effect.
Thanks again!
Thanks … a lot !
Hi! This is awsome article, but I can’t do following with this approach:
I want to have this effect of tranistion with two images, one is b/w and other is in color. I also want to caal them from database, so I need some script to operate with larger number of images … and idea how to do that?
Thanx for helping!
Very useful! thx
I think I am confused. I want to use one button to go to a site…and if they hover over the button I want it to change colors…what is the EASIEST way to do that.
Hey RT, you can use something like this: http://inspectelement.com/tutorials/create-a-button-with-hover-and-active-states-using-css-sprites/
Its much more simple and is a better way compared to this technique (this tutorial should not be used for buttons)
If you are up for it, these are very nice too: http://www.webdesignerwall.com/tutorials/css3-gradient-buttons/
Good luck!
great job :d
lov it
now show me the download link
hi – i’m trying to work out how i can get this working on wordpress. i have a custom designed template that uses posts as thumbnails. i’d like to get this effect on the post image.
is this possible?
@Adam – Yes, its possible, just make sure you upload images that has both grey scaled + colored like this : http://www.sohtanaka.com/web-design/examples/hover-over-trick/step1_a.gif
@soh – i’m lost. i can’t work out how/what to change in the jquery script. i have a div that my posts are in called #project – but as they aren’t a list it’s not working.
can anyone please help?
Change two things if you want to reverse;
1: Reverse the photo’s in the sprite, placing greyscale above and color below
2: Change the 0 to 1 and the 1 to 0 in the jQuery script
Cheers :)
Hi guys!
I’m not a coder or something, i am new to web design and stuff…but here is how i managed to make this work in wordpress:
Tip* First of all open the demo and look at the source code so you can see the hole thing on one place.
1. Copy “jquery.min.js” or what ever you wan’t to be the name in your theme directory (or whereever you want), or just use the hosted at google one.
2. Call the .js file in your header.php (or again just copy and paste the link from the tutorial to use the google one)
3. Also in your header copy and paste the aditional “jQuery actions being performed”. Just copy the code from this great tutorial.
4. Copy the .css code (again from this post) in your style.css (the css file or files of the theme you are using). You may need some editing to make it looks ok with your theme.
5. Make a new post/page in your wordpress blog and just use the html code provided in this post. Tip* You can just copy the html code from the demo and change the urls and the pics. Use only the <ul and <li tags…not the hole html code.
I hope this helps. Sorry for the bad English! :)
Hi!
I apply this awesome effect in my site (on the main page in the right “Najnowsze Wpisy”) , but in Internet Explorer this effect don’t work in my site… what I am doing wrong?
Krzysztof I believe it’s a CSS problem. If you are using different .css files for firefox and ie (like me), copy the code in the other file too, if not try calling the .css (the part that is for this effect) in your header.php before head tag.
Also it may be cos you are not using the right class. Use the ul.imageslery in the html not the “gallery” class, the “gallery” class may be overwritten somewhere.
Does anyone know how I could add a caption to appear on the hover state aswell as the image changing?
I love it!
Nice work!
will be pretty useful in my portfolio…
Thx for sharing
Hey, great! But how to do this whit two images instead? Going to use this for thumbnails in an image gallery.
Thanks!
Hello, I’m trying to use this awesome script on my webpage, but it isn’t working. I donpt know whats wrong. Everything seems to be fine, but I don’t see that effect on hover. Here it is: http://www.apfoto.site90.net/gallery.php
Thanks to anyone who can help me…
Doesn’t work for me. I get the same problem as Liz
“LIZ
Great Tutorial – but I’m having a huge issue with my images. Check it out, instead of greying my image becomes the background???
http://shocktheworldart.com/jquerytest.html“
im having the same issue as liz and riley… any thoughts on what we are all doing wrong?
thanks!!
Sarah, Riley and the other guy. It’s from your images. You have changed the css width and height but the dimensions of the pics is wrong. I will see tomorrow at work the things that i used do make it work. But you only have to edit the size of the images i am sure!
hey i love the effect but it wont work for me the image wont work but your other one worked fine :) great tut keep it up :) x
thanks!!
Just what I was looking for… I love your designs as well… Great work!
Hi! Great tutorial!
I’ve used this technique a few times. I’ve been working on my sister’s blog, and this technique works in all other browsers, but Safari. I’ve been trying to figure out what I’ve been doing wrong, but I can’t figure it out.
I’ve checked the dimensions of the photos and they match the dimensions in the css. Please help me!
This is a WordPress blog and I used Thematic to build my theme.
http://www.wondermentwoman.com
Bud I love your website and your tutorials are great! I will definitely be referencing you for my upcoming design site.
how abou from Greyscale to colour Hover Effect
can u show me the example please
thanks
hi , i got problem the image was not faded …just the background was changed in gray….can any one help me plzzzzzzzz where i did mistake…? i found that js was not respond and my code was
Wow, nice one. Though I need to make from grayscale to color than color to grayscale. But hope can make it work with the help of this one. thanks!
You’re awesome.
That is all. :o)
it looks good…
Speak Your Mind...