#82: CSS Image Switcher

Roll over a link, watch the image above change. That's what we build in this screencast, only we don't use any JavaScript to do it. The trick is some simple z-index switching on hover and a bit of absolute positioning.

Links from Video:


  1. User Avatar
    Daan Schaart
    Permalink to comment#

    Thanks, that was really useful!

  2. User Avatar
    Permalink to comment#


  3. User Avatar
    Permalink to comment#

    Great screencast, Chris.

  4. User Avatar
    Permalink to comment#

    Another useful tool, its a work of art.

  5. User Avatar
    Permalink to comment#

    Very useful thanks man!
    does z-index work in all browsers?

  6. User Avatar
    Tim Ward
    Permalink to comment#

    Remember, you can set the Image you want on top as z-index 1, and make the hover z-index be 2. This allows you control of what “default” image you want displayed on top (like in case of a portfoilio.

    My question is – How do you set an Image to be on top (until the roll-overs) that is not part of the rollovers. Say, a Logo is at z-index 1, and the rest of the images are at z-index 0 until the rollover state of z-index 2.

    So – 5 images, and 4 hover z-index changes. the 5th being a default image always on top.

    It’s a Great non javascript onhover trick. Thaks.

    • User Avatar
      Jeremy Carlson
      Permalink to comment#

      Actually, that would be extremely easy. If you download his source code, add an a tag above the one with the id of “one”, and give the new one an id of logo. So you have this:

      a id=”logo”
      a id=”one”
      and so on

      In the css create #logo, give it a background, and give IT the z-index of 2, and take the z-index off of #one.

      Nice little bit of css work there Chris. Personally I would have gone the javascript way, but I actually might use this sometime. What I like about this is, I didn’t even have to watch the screencast to get it. Made sense just looking at the css. I love seeing this kind of stuff.

  7. User Avatar
    Permalink to comment#

    yeah yeah an other nice and grreate screencast keep it Chris .

  8. User Avatar
    Permalink to comment#

    That was shiny!. Really nice tutorial. Now.. let’s see on what real test case i can use it upon :D

  9. User Avatar
    Permalink to comment#

    Very nice . Good tut Chris .

  10. User Avatar
    Permalink to comment#

    nice one – really simple round-up yet again.
    I know of variuos ways to accomplish this, but hav never seen one that’s so simple, with so little markup. Good job!

  11. User Avatar
    Permalink to comment#

    Thanks Chris! Great tip as usual!

  12. User Avatar
    Stephanie Chung
    Permalink to comment#

    I have always been curious about a unique way to use z-index. Usually it’s just use to position layers on top of each other but… this is still doing that but having a better use. Great idea! :)

  13. User Avatar
    Permalink to comment#

    Another great tutorial, nice idea, thanks Chris!

  14. User Avatar
    Permalink to comment#

    A awesome tricky for images roll-over in pure css.

  15. User Avatar
    Permalink to comment#

    Great, many thanks for this!

    I recently tried to do a roll-over on an image that I have fade-in with JS — couldn’t get it to work. I’m going to try again with this technique.

  16. User Avatar
    Permalink to comment#

    Wow… Chris, what happened?

    Did you get religion or something? From the absolutely worst screencast you’ve ever done (Ajaxing WordPress) – and I’ve seen them all; to probably the best! From rambling, confusing, unorganized and sloppy to precise, concise, planned, organized and extremely focused and on task!

    Don’t know if you have been officially “baptized” into this new religion or if you are merely “taking the missionary lessons” but this was enjoyable and REALLY GOOD! Keep it up!

    • User Avatar
      Mike Dedmon
      Permalink to comment#

      Ok – I noticed the difference first thing as well, but one of the things I love about Chris’ screencasts is they seem real and accessible. It almost seemed like someone had scolded him and he was trying too hard to be “better”.

      Granted the “Ajaxing WordPress” was one of the shakier, but today’s seemed just a little too rehearsed and formal. I miss the singing/humming figuring things out / troubleshooting stuff.

      This was a great screencast and great info, but don’t change too much. You’ve always been GREAT in these.


      P.S. Please don’t let it be that he “got religion”… :)

    • User Avatar
      Permalink to comment#

      Well, he did mess up the #switcher-wrapper thing. There’s one unrehearsed part of the show.

    • User Avatar
      Chris Coyier
      Permalink to comment#

      I was just trying out a new style kinda, but don’t get too used to it =)

  17. User Avatar
    Mike Dedmon
    Permalink to comment#

    Something else I learned today was a better understanding of z-index. I thought that z-index incremented automatically for each item that was loaded in order. Now I understand that z-index is more like a series of glass shelves…

    shelf 0 is default – each item “placed” on that shelf covers the item below it, but on the same shelf.

    z-index really indicates a higher shelf to place things on. So, presumably if several items had the same z-index of 10, then they would be “placed” on shelf 10 above shelf 0 and each item would still cover the item below it on that same shelf based on the order that it was loaded.

    I don’t know if that makes sense to anyone else, but it completely clarified the z-index behavior for me.

    Another great reason to watch these screencasts…

    Thanks, Mikey

    • User Avatar
      Permalink to comment#

      That would be really confusing if z-index updated for every element placed on the page, heh. You would have to work fairly closely with the document to get that one to work.

      Good analogy!

  18. User Avatar
    yubo zhou
    Permalink to comment#

    .image-link:hover { z-index: 100;}


    .image-link:hover { z-index: 100;cursor:pointer;}

    Solve the problem can not be realized under IE6

  19. User Avatar
    Permalink to comment#

    Good stuff Chris. I discovered your site a few weeks ago and have been loving it. Keep it up!

  20. User Avatar
    Permalink to comment#

    Thanks Chris!

  21. User Avatar
    Permalink to comment#

    A good exemple of CSS power, with a little ingenuity you can make a great effect.
    Well done.

  22. User Avatar
    Stanley -- TC
    Permalink to comment#

    Brilliant! :) Thanks a lot. You explain things very clearly to your audience. Bravo. :)

  23. User Avatar
    Phil Dahl
    Permalink to comment#

    So useful, was wondering how to do this for a while and here it is at my door step! Thank you so much!

  24. User Avatar
    Permalink to comment#

    thank you so much for your wonderful Commentaries. if possible how i can Resizable the pictures automaticly?

  25. User Avatar
    Permalink to comment#

    Wow, that was really practical!

    But I really missed the signature welcome “Hellllooo everyone, this is Chris from CSS-Tricks with video screencast number eighty two! In which the topic today is…” and the CSS-Tricks wallpaper. I agree with Mike above; this one seemed a bit too formal. My first impression was that this was for another site/event, but was also posted here as a regular screencast.

    • User Avatar
      Phil Dahl
      Permalink to comment#

      That doesn’t make sense. The opener is fine and to the point and matches the site’s design.

  26. User Avatar
    Permalink to comment#

    I don’t think that using CSS to accomplish this is the best tool for the job.

    This is semantic:

    1) Databases are for, well, data
    2) Server-side code is for reading and writing of data
    3) HTML is for markup (marking importance of data, delineating data)
    4) CSS is for presentation of that markup
    5) JavaScript (or any client-side scripting) is for when the information contained in the markup must change.

    I would call this a critical change in information in the document.

    Something like a cool effect on a sidebar where the image changes as you click–that’s CSS’s job – it’s purely presentational. This, however, is altering the structure of the document and would be better served with a

    $("img").attr("src", "1.jpg");
    or document.getElementById("switcher").src = "1.jpg";

    • User Avatar
      David Chambers
      Permalink to comment#

      I totally agree, Christian. Chris’s lackadaisical separation of content and presentation has been noted on more than one occasion (by me and by others).

      In fact, I was so horrified at the prospect of this approach actually being implemented that I set to work immediately on my own CSS-based solution.

      Fourteen hours later I’m pleased to be able to link you to CSS image switcher (done the right way) and the CSS image switcher demo.

      My solution is built upon meaningful markup which ensures that the content is always accessible – to those on mobile phones, to those using screen readers or feed readers, and — crucially — to web crawlers.

      Please, do not use Chris’s approach until you have understood its inherent failings.

  27. User Avatar
    Permalink to comment#

    Nice Trick by Z-index.
    Any hack for IE 6.0? to get this trick work out.

  28. User Avatar
    Permalink to comment#

    Thank you for sharing this beautiful

  29. User Avatar
    Permalink to comment#

    Hey Chris, I ran into your site four days ago nothing sort of genius!! I’m just learning Java script and so far with your tutorials I have improved. Keep up the good work.

  30. User Avatar
    Permalink to comment#

    I was very happy to stumble upon this article. I have used z-indexing before, but never thought to use it on :hover before. I think I’ll be giving this a go.

    Thanks V much

  31. User Avatar
    Permalink to comment#

    Great use of the Z index!! Thank you for this tutorial..


  32. User Avatar
    Permalink to comment#

    Not Support IE6.
    .link:hover {}

    Someone can hack this issue?

  33. User Avatar
    Permalink to comment#

    Awesome! Thanks a lot!

  34. User Avatar
    Permalink to comment#

    Another great idea to insert in my projects, thanks Chris!

  35. User Avatar
    Permalink to comment#

    Amazing trick!
    im going to use it..

  36. User Avatar
    Zach Walsh
    Permalink to comment#

    This is a great trick. It is always nice to do things with little or no plugins.

  37. User Avatar
    Permalink to comment#

    Great stuff!! I’ve used it on my site and I love it. Keep up the good work and I’ll keep watching and learning.

    Chris R.

  38. User Avatar
    Permalink to comment#

    Real use css skills, thank you

  39. User Avatar
    Permalink to comment#

    The next screencasts???

  40. User Avatar
    Permalink to comment#

    which html editor do you use? does it has a windows version?

  41. User Avatar
    Keith Wiggans
    Permalink to comment#

    Crazy genious! You front-end design guys consistently like to make my jaw drop with your trikiness.
    Keep up the great work.

  42. User Avatar
    Permalink to comment#

    Is there a way to do a onclick instead of a hover?

  43. User Avatar
    Permalink to comment#

    sure there is a way send me message to explain you…

  44. User Avatar
    Permalink to comment#

    Thanks, very good teacher !!

  45. User Avatar
    Saeed Neamati
    Permalink to comment#

    I wonder if CSS Transitions also support z-index property. If they do, then this switcher can become a fantastic switcher by fading out the current picture and bringing up the new on.

    This was a great tutorial Chris. I loved the idea of remote linking. Thanks.

  46. User Avatar
    Permalink to comment#

    This is great, but the downside I see here is images are not printed as they are background images. :-/

    Overall congrats for fantastic work you do!!!

  47. User Avatar
    Permalink to comment#

    Thank you sooooo very much for this tut-n-code! I was looking for something like this a while ago. Very useful!

  48. User Avatar
    Permalink to comment#

    Very nice trick using the z-index. but forgive me for being a newbie, but how do you get the picture to stay if i clicked on an item? it seems to always revert back to the primary picture. Can it be done without using any javascripts!?

  49. User Avatar
    Permalink to comment#

    Also, I was wondering if there is a way to do this having at least one of the hover states be default when page loads? I am using this for product rollovers and need content to display even before a rollover. Client wants one default hover state “on” all the time. Using Z-index and simply changing the display would work great except the logos are in a horizontal line, not stacked on each other and and the rollover has an image swap . Any suggestions or Javascript the only way to accomplish? Thanks!

  50. User Avatar

    Thanks for this!

    Is there a simple way to to keep the last image you rolled over on top after you roll out? By default it goes back to the first image.

  51. User Avatar
    David Parsons
    Permalink to comment#

    Been looking for something like this for a while. Thank you sir!

  52. User Avatar
    Rifad Daniel
    Permalink to comment#

    Obviously it can work. I appreciate this work. Thanks a lot.

Leave a Comment

Posting Code!

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.