How to Create Image Swap Effect using CSS


The image swap effect is a very common thing for those freelance web designers and those working in web design companies. For navigational purposes, it can make menus much easier on the eyes by highlighting the user’s pick. This helps to prevent misclicks, and looks nice as well. When you want to create an image swap effect, the standard procedure is usually to throw in an OnMouseOver event in JavaScript.

Unfortunately, there are a number of disadvantages to this approach, like the fact that a large number of people have JavaScript disabled in their web browser for security purposes. Thankfully, the same effect can be created using standard HTML and a neat trick using CSS.

Here’s how the trick works for CSS. First you’ll create a division in your code with the div tag and give it a class. Inside of the division, you’ll place the image in standard image tags that will be used for when the mouse is not over the designated area. Next, you’ll add a background image to the division’s class using CSS, and this image will be the one that appears when the mouse is over the designated area.

Finally, you’ll add a piece of CSS that changes the display attribute to “block” for the anchor tags within the div class you created, as well as changing the display attribute to “hidden” for when the mouse hovers over anchors tags inside of that division class.

While this is a little tricky to understand conceptually, in practice it’s much easier to see. Here is a sample piece of code that achieves this effect:

<a href="#">
<img src="logo.gif" width="187" height="136" alt="" />

And the CSS to go along with it:

div.nav {
 height: 187px;
 width: 136px;
div.nav a, div.nav a:link, div.nav a:visited {
div.nav img {
div.nav a:hover img {

The way this works is that when you hover over the anchor image in the swap division, the CSS hides that piece of content so that only the background image of the division is seen. It’s a neat trick that a lot of people, even professional web site programmers, don’t know about.

When using this, there are a number of important points to keep in mind. Before you start working with the code and CSS, you should have the images and layout prepared. If you don’t, then any small change in your images will require multiple changes in your code, and this wastes time and can lead to mistakes that are hard to detect. Next, remember to place the “before mouseover” image in the image tags, and the “after mouseover” image as the background.

As you might expect if you are familiar with web design, you’ll need to make an adjustment for users on Internet Explorer. The reason for the tweak for Internet Explorer is that this particular browser has problems storing background images in the cache. This results in a sort of random blue and red flashing when the mouse goes over the division image. Also with IE, you’ll need to make sure that you don’t have the “background-position” attribute set for this fix to work since that will bring back the flashing problem. Here is the fix, which can be put in with or without the conditional comments.

< !-- [if lte IE 6]>
< style type=”text/css”>
div.swap {
background-repeat: no-repeat;
div.swap a:hover {
visibility: visible;
< /style>
< ![endif]-->

One disadvantage of this method is that it will greatly increase the size of your CSS file if you use it for a large set of menus, but this is minor since CSS files load very quickly as they are just simple text. It’s also not a problem for file sizes on the server since most people use some form of unlimited hosting.

Download sample here.


  1. jimmsly Nov 20, 1:53 pm

    Just search for css sprites (particularly ‘A List Apart’s very famous article on this subject) and :hover – and you’ll see that this particular problem was solved long ago, in a much more semantically clean, and concise way. Tom is completely correct.

  2. Marc Jan 23, 1:36 pm

    I’ve used this method back in 2008 for creating buttons that light when you mouse over. Then looked “pressed” when you clicked them. It was easy enough to do, but there was one snag. You had to have all your images pre-sized for your page. You couldn’t do the CSS animation trick AND the image resizer trick at the same time. Any ideas?

  3. Ryan Jul 23, 10:49 am

    tom, care to show us a better way?

  4. Kristi Aug 2, 11:27 pm

    you basically create an image [sprite] that combines both link and hover state and change the positioning to show the version you want. Makes sense.

Leave a Reply

* Minimum length: 20 characters