Grow your CSS skills. Land your dream job.

Silhouette Fadeins

Published by Chris Coyier

Some friends of mine's band recently went through a small member lineup change. They needed to replace the photo on their homepage. I thought it might be fun to do something slightly interactive there. We went with silhouettes of the band members, which fade into real photographs upon rollover.

There are probably quite a few ways to do this... This one just popped into my head and I went with it. The idea is to have a div with the silhouettes as a background image. Then have four images within that div, all of the exact same size, with each band member highlighted. These images are hidden by default. Then have four absolutely positioned region sitting on top in the div. These are the rollover area / links. In the jQuery, we watch hover events on them, and fade in the appropriate image.


Like I mentioned, just a div with four images inside it and four rollover areas. All with unique ID's and common class names.

<div id="home-photos-box">
    <a id="aller" href="#aller" class="home-roll-box"></a>
    <a id="neil" href="#neil" class="home-roll-box"></a>
    <a id="aaron" href="#aaron" class="home-roll-box"></a>
    <a id="scott" href="#scott" class="home-roll-box"></a>
    <img src="images/guys-aller.jpg" alt="" id="image-aller" class="single-guy" />
    <img src="images/guys-neil.jpg" alt="" id="image-neil" class="single-guy" />
    <img src="images/guys-aaron.jpg" alt="" id="image-aaron" class="single-guy" />
    <img src="images/guys-scott.jpg" alt="" id="image-scott" class="single-guy" />


Commonalities covered by class names (e.g. position style), unique things covered by the ID's (specific left position).

#home-photos-box { float: left; width: 352px; background: url(../images/guys-allblack.png) no-repeat; padding: 334px 0 0 0; position: relative; }
#aller { left: 0; }
#neil { left: 25%; }
#aaron { left: 50%; }
#scott { left: 75%; }
.home-roll-box { position: absolute; z-index: 1000; display: block;  height: 334px; top: 0; width: 25%; }
.single-guy { position: absolute; top: 0; left: 0; display: none; opacity: 0; }


Watch for hovers, when they happen, pull the ID of the hover area, which corresponds to the ID of the image, and fade it in. We make sure to use .stop() here to prevent queuing up of animations and we're using an opacity setting instead of .fadeToggle() which likes to do partial-fades when moused in and out too quickly.

$(function() {

    var name = "";

    $(".home-roll-box").hover(function() {
        name = $(this).attr("id");
        $("#image-"+name).stop().show().animate({ opacity: 1 });
    }, function() {
        name = $(this).attr("id");
        $("#image-"+name).stop().animate({ opacity: 0 });


View Demo   Download Files


  1. Seb
    Permalink to comment#

    Don’t see anything on the demo page….

  2. Permalink to comment#

    Dude, add return false to stop the anchors coming into action, i know the click event isn’t bound to do anything but it’s still annoying :p.

    Nice demo though, works really well with this set of images and a nice idea all around :)

    • That’s NOT in there so that you can see the hashtag and see that the links are real live links. If you don’t want them to be in your implementation, add it, or make them divs instead of anchor links.

    • Will
      Permalink to comment#

      I think the existing implementation is good, and makes sense. This would logically go on a page with info about the band members, so the individual member silhouettes are ideally suited to be links that could be marked as active or not, so when you click through them a div below the group of silhouettes could be updated with bio info on each member, leaving that member photo highlighted.

      By implementing it as Jamie refers to, this functionality wouldn’t be as apparent.

  3. Simon
    Permalink to comment#

    Doesn’t seem to work in IE(8)

    • Permalink to comment#

      Pretty slick! Great stuff as usual, Chris.

    • Permalink to comment#

      Don’t work in IE7 as well.

    • Justin
      Permalink to comment#

      Yes very cool idea. For me in IE 8, the first guy I hover on fades in and out but then the effect stops.

    • Justin
      Permalink to comment#

      Very cool idea.

      For me as well in IE 8 it doesn’t seem to work fully. The first guy I hover in will fade in and out, but nothing after that.

    • Who cares about IE anyway?

    • Permalink to comment#

      Annoying as IE is every designer should still care about it. Simply saying “Who cares about IE anyway?” isn’t going to suddenly make all those IE users out there disappear and there are still quite a few of them.

    • Permalink to comment#

      Agreed, besides, it doesn’t work well in IE8 as well

    • Al
      Permalink to comment#

      I don’t understand the comments about IE.

      I maintain 2 non-technical web sites and if I quit supporting IE, then the sites may as well be taken down, not many other web browser users access those web sites, combined total less than 25%. like it or not, IE is a dominant browser in many non-technical areas.

      demo does not work in IE7 for me either, the browser I use most of the time, force of habit I guess.



    • Will
      Permalink to comment#

      I agree Al,

      While I dislike the quirky nature of IE, and the fact that most style implementations require some extra hacks and fixes to make things work properly in IE, there is no denying that it is a dominant browser.

      On the busiest site I maintain, (with an average of 1,000 unique visits/day) the top three browsers are:
      IE – 71.78%
      Firefox – 15.17%
      Safari – 10.49%

      Chrome comes in at a lowly 1.74%, and all others are less than 1% combined.

      So flat out refusing to support IE is just not a viable option, especially if it’s for something mainstream like an ecommerce site.

    • Al
      Permalink to comment#

      the fact that this demo does not wok in IE7 kinda destroys the intent of the article, sorry Chris

      I won’t use an effect if it does not work in IE, or at least IE7 and IE8, IE6 is not as important. I do notice on my site stats that IE8 is taking over from IE7 in usage, maybe the influence of Windows 7.


  4. Just wanted to tell you how i would have done it.

    Start with a div container with a background image containing all the silhouettes.

    Then position four divs inside containing the images. Images would be set to 0 opacity until the div is rolled over.

    Lets say my container has the id ‘container’. I can now use the jquery function: $('#container div img').hover(); and each image can be faded in or out when hovered over. No need to give id’s to the inner divs, and much easier to extend.

    Thanks for the great site,
    Ive been here for a month now, and i find it useful!


    • SFdude
      Permalink to comment#

      Sounds good –
      but you can you supply a link
      to a simple Demo page of your version?


  5. That is cool!!!

  6. Permalink to comment#

    Very cool Idea Chris, excited to try this one out!

  7. Thats pretty cool.. Im really starting to get into jQuery, I would have probably done that in flash or just with a standard roll over effect, but not with jQuery can get the desired effect without messing around in flash etc. Thanks for the tutorial, will def come in handy.

  8. senshikaze
    Permalink to comment#

    I love the music. Tell them they have gained a new fan.
    (the silhouette thing was cool too, but you already had me as a fan :) )

  9. Batfan
    Permalink to comment#

    Great one, Chris! I have a new project that I’m working on that this would be great for :)

    That being said, it does not seem to work in IE7 or IE8. Only one of the band members will fade in and they will only do it once.

  10. Permalink to comment#

    Can you say perfect timing? I have been trying to figure out a good way to do this for the last two days and have not been successful.

    Thanks Chris!

  11. Rick
    Permalink to comment#

    Something like this would be better and easier done in Flash. Cool effect though.

    • Permalink to comment#

      The point, I think, is to do it with CSS and not Flash. Hence CSS-Tricks.

      I think people have been too quick to depend on Flash for different features, which leads to a heavy and messy site. Luckily, the growing popularity of JS libraries like JQuery and Mootools have dramatically decreased the number of sites that do not work on my mobile phone!

    • Yeah sure. For that you need the following:
      1. As a developer, license for Flash (How else would you develop otherwise)
      2. As a visitor, flash plugin
      3. As a visitor, good bandwidth
      4. As a mobile user. A computer at hand

    • bjerh
      Permalink to comment#

      That fourth argument of yours is invalid. Most cellulars isn’t equipped with a JS rendering engine. I mean, besides the newer smart phones on the marked most cellphones still got way outdated browsers installed only capable to render HTML (and WAP etc.) and images.

      But I’m totally with you. I think that JS is the better choice over flash in most cases and in this particularly.

    • Dave
      Permalink to comment#

      So, you’re saying the argument is invalid because some ppl are still using their nokia brickphone from 1999? You would acknowledge that more phones have js than flash, wouldn’t you? That would seemingly make it a valid argument.

      Anyway, if you look at some analytics, you’ll see a lot of folks are using these things called iphones now. I think that guy from dodgeball makes em.

    • bjerh
      Permalink to comment#

      I agree with you that recent smartphones has been equipped with modern-ish browsers, including JS support. FlashLite has been supported for I don’t know how long. But fact is that it’s not everybody who runs around with an iPhone in their hands. Or a Palm for that matter. For example: Nokia is still the biggest player on the mobile phone market. Besides from their disgustingly overpriced super-duper smart phones, most of their phones is ill equipped when it comes to rendering HTML, let alone running JS code. And unless you bought a new cell phone within the last couple of years, chances are you haven’t got decent JS/Flash (non lite) support on your celluar.

  12. Permalink to comment#

    Rolling over them makes me want to click them an get more info about each one. Also, isn’t it better to have them appear as a band and not as silhouettes for branding purposes? Just my .02.

    • FGutz
      Permalink to comment#

      you make a valid point. It’s a really great, and a simply done effect. But why would you not want them seen when you first load their homepage? Maybe if this effect was done in the band bio page and then when you click on each member you would see specific info about that member, or something like that. Just a thought.

    • Definitely a valid point. On one hand, the mystery of it is kinda fun and may actually work better. On the other hand, not seeing all their faces together might hurt a bit. Their whole website is kind of under review right now, and I agree I think this kind of thing would probably be better served on a individual biographies style page.

    • Would there be a way to make all four images fade-in automatically after a predetermined length of time?

      This way, when the user first gets there, they can hover over the silhouettes all they like, but they’ll still get the chance to see the band altogether?

    • bjerh
      Permalink to comment#

      Sure… You can always call the fade logic, based on a JS setTimeout().

  13. Permalink to comment#

    Oh, that’s nice…

  14. Permalink to comment#

    Nice Trick:
    name = $(this).attr("id");

    Good to konw!

  15. Neat effect.

    I have a question however, and I realzie this might be slightly offtopic, but it’s to do with the hover effect so I’ll post it here anyway.

    In jQuery, is there a way to fire the CSS :hover event? I know you can fire the JS one, but I’m in the situation where I have a styled anchor, normal and hover states defined in the CSS, and I’m trying to – on a certain action – change the styling of the anchor to match the :hover event.

    At the moment, I’m simply pasting the relevant CSS into a .css() command, but it’s a pain to update if I change the stylesheet. Is there a more elegant solution?

  16. Anthony
    Permalink to comment#

    This looks awesome! Nice post Chris.

    It’s a rare thing for a band to only have ONE band image on their website so I don’t think it’s fair to discard the idea right off the bat.

    I agree that this probably wouldn’t be great to have on a main ‘featured’ image of the band, but there’s certainly room for it to be used to great effect in lots of other places (like a biog page as mentioned previously).

    Thanks again Chris for more cool stuff!

  17. John
    Permalink to comment#

    That is a really great effect! Looks awesome!

  18. Just today I finished one section of my site and thought to include this very fade-in technique!

    Yours is simple, easy-to-understand and looks like I’ll be able to adapt it easily to my needs. Thanks a lot Chris, and great to see your site was reinstated.

  19. adam
    Permalink to comment#

    cool effect…i can think of many ways to use it…and probably will. so thx!

  20. Demo not working… I’m using FF 3.5.5.

  21. Jess
    Permalink to comment#

    I like how the banjo appears to be giant, fuzzy boots in the silhouette.

  22. Permalink to comment#

    Demo is not working ;(
    Mac OS 10.5.8 … Safari 4.0.4

    Kind regards

  23. Permalink to comment#

    Strange :P
    After the second reload it works … Very nice!

    Kind regards

  24. I’m curious as to why you decided to put the images outside of the anchor tags. I would have put them inside and done something like this:

    $(function() {
    $(“.home-roll-box”).hover(function() {
    $(this).children(‘img’).stop().show().animate({ opacity: 1 });
    }, function() {
    $(this).children(‘img’).stop().animate({ opacity: 0 });

    This way you’d have less markup in the HTML and less JS code as well.

    • Because the anchor tags, the .home-roll-box’s, are only 1/4 the size of the whole div and positioned specially. the images were children of the anchors there would have to be another whole set of rules repositioning them into place, different for each image. I’m not sure what advantage that would have.

    • I was thinking that each of the fader images were of only one person without the silhouettes. If this were the case and there wasn’t any overlap you could just put the image in the anchor tags and position the anchor tags.

      However, since there is some overlap and dealing with opacity in IE6 is a pain in the butt I fully endorse the way you did it. :)

  25. Permalink to comment#

    Chris, any chance you’re gonna look into making it IE compatible?

    I really like the effect, although I think the code could be made a little cleaner (like suggested here and there)

    • senshikaze
      Permalink to comment#

      why not try and make it ie compatible instead of asking chris to? give back instead of whine.

  26. Alex
    Permalink to comment#

    I first saw this effect on Doomtree’s website, came out really nice –

  27. Permalink to comment#

    It is working nicely in FF 3.5.5 !

  28. Permalink to comment#

    Super cool effect – and great implementation for your friend!

  29. Hey all —

    I think I fixed the IE issues. Let me know.

  30. Permalink to comment#

    cool, article and thanks for introducing me to an awesome band, too!

  31. Permalink to comment#

    Hi all!

    Chris, I’ve simplified your version a little bit and tested it in IE 6 and 7, Firefox, Opera and Chrome. Also for JQuery I’ve used fadeIn and fadeOut functions and no special CSS.

    Check it out:

    • This is cool but you aren’t using .stop(), which means the animations queue up really fast multiple mouseovers. Then if you do use .stop(), you’ll run into problems with fadeIn/Out not returning to full values, that’s why I used the opacity animation instead.

      I’m really struggling trying to find a way where a complete animation cycle without using stop or using it, but smarter in some way.

      The only one that does nice complete cycles is the top example, the others either don’t do complete cycles or are jerky.

    • Permalink to comment#

      I’ve played with callback that execute when animation is over.

      Here is the solution that does the job for first example on your test page):

      var inAnimation = new Array();	
      $(function() {
          $("#not div").hover(function(){
      	if (!inAnimation[$("#not div").index(this)] ) {
      		$(this).animate({ width: "200px" });
          }, function() {
      	inAnimation[$("#not div").index(this)]  = true;
      	$(this).animate({ width: "100px" }, "normal", "linear", function() {
      		// callback, to enable animation again
      		inAnimation[$("#not div").index(this)] = false;
    • I added that one to the demo, but it’s still queing up animations.

      Here is my latest attempt:

      $("#animate-test div").hover(function(){
          $(this).filter(':not(:animated)').animate({ width: "200px" });
      }, function() {
          $(this).animate({ width: "100px" });
    • Permalink to comment#

      Line var inAnimation = new Array();
      should be outside $(function()), in global scope.

    • I moved it outside, but that doesn’t make any difference. It was declared outside of either function using it so they would both have access. It’s the queuing up that is the problem.

    • Permalink to comment#

      Yes, your right. I was testing in my Firefox on Xubuntu at home yesterday and it looked better, but now that I’m looking in Windows not so good.

      But your last solution works pretty good. So, keep up the good work.

      Maybe I’ll give it a try later – with different approach.

  32. Johnny
    Permalink to comment#

    Why not use an image map for this?

    • Great Demo, what I was looking for…

      I like to use it with a Map with some countries in, but I would like to name these areas too.

      Would be great if the names of the Band would show up too like a Menu, if you hover the Band silhouettes the names will be highlightet. (Would be great if that would work too if you hover the names and the silhouettes would show up.

      …Johnny: I think image maps are possible too, but make more work, and maybe are not that smart. It is a CSS-Tricks Site and image maps dont have to use CSS only Java Script.

  33. Christ, I know this is a little off-topic, but do you have a good tutorial or resource on how to create good silhouettes (from choosing a good image/form to silhouette through the process of actually creating it)? I ask because I’ve always had trouble with them.

  34. kesc
    Permalink to comment#

    I’m at work and on IE7, and yes the demo works just fine.

    Neat trick, gave me some ideas. Thanks!

  35. Permalink to comment#

    Good write-up.

    However, I must politely say that I’m not a fan of this specific thing. Though it’s not navigation, it reminds me a little of ‘mystery meat’.

  36. Maggie
    Permalink to comment#

    Great tutorial, it’s very useful. thanks.

  37. delux_lux
    Permalink to comment#

    hi all u
    I’m work at firefox the demo works fine. but not work in ie 6.
    Lovely Tricks.

  38. delux_lux
    Permalink to comment#

    oke Its Modified Thanks to Css-tricks
    & bkuzmic

  39. Permalink to comment#

    Hello everyone!

    I’ve fixed queuing of animation effect:

    See again in demo:

  40. Eamonn
    Permalink to comment#

    I knew I find it eventually! There’s a similar effect on the website of the Aussie band The Cat Empire. You can check it out here,,,

  41. Dennis
    Permalink to comment#

    Sort of unrelated to CSS…But I know the new bass player of the band. Never quite know what you’ll find! Great effect and tutorial.


This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".