Image mouseovers without javascript - CSS & Sprites

Date: 3rd March 2008 at 1:27 am | Filed under: development, scripts | Author: Sam Burdge

This article is an extension / improvement upon another article I published on my site previously: Simple Javascript for Image Mouseovers. As I am always looking for improved methods, I was discussing the pitfalls of the javascript method with a friend (and occasional comment writer / contributor to my site) who pointed me in the direction of CSS and image sprites. This lead me to research the topic further, and I found two articles in particular which were incredibly useful:

  1. Fast Rollovers by Petr Stanicek
  2. CSS Sprites: Image Slicing's Kiss of Death by Dave Shea

Rather than reiterating what is written in these two articles, I will instead try to summarise it and provide step-by-step instructions of how to implement the technique.

Advantages of this method:

The main advantages of this method over the javascript method are as follows:

  1. Quicker loading of the mouseover
  2. Lighter simpler code in the form of an html list
  3. Doesn't rely on the user having javascript enabled in their browser

Basic principals:

The basis of this technique is to include all states (up, hover, visited etc.) for your button within one image file - called a sprite. This file is set as the background for your button or set of buttons (for a site nav etc.) and, using CSS, it is positioned appropriately to display the correct state for the button.

Examples:

This example will show exactly how this works for a set of images layed out horizontally: Example 1
This example will show how it works for a set of images stacked vertically: Example 2

Both examples work by the same principle. Feel free to view the source code to see exactly whats going on.

The tutorial:

This tutorial assumes you have a basic knowledge of html, CSS and image creation using photoshop or other similar image editing software.

Step 1 - create the sprite:

To create the image sprite in Photoshop (or the image editing software of your choice) it is best to create the inactive up (a:link) states for your buttons first. For the sake of this example let us imagine it is a horizontal row of 4 buttons (as in Example 1), with a height of 80px. Each button has a width of 80px, giving an overall image width of 320px. So, to recap this first stage:

  1. Create an image 80px high and 320px wide.
  2. Create 4 buttons in a row, each with a width of 80px .

You should now have something similar to this:

Example Sprite 1

The next step is to create the over (a:hover) states for your buttons. The first thing to do is double the height of your image canvas, keeping your first row of buttons aligned to the top of the image. This will give an overall image height of 160px. Duplicate your first row of buttons and move the duplicate layer down 80px so it is siting directly below the first row, then modify the colours / graphics to how you want the over state for your buttons to look. To recap:

  1. Double the height of your image.
  2. Create a second row of buttons for the mouseover state.

Your image should now look something like:

Example Sprite 2

If you wish to add extra states, perhaps for when the button is clicked (a:active), repeat this stage again, adding 80px to the height each time.

Note: it is important to be precise in your measurement, use rulers and guides if necessary.

Step 2 - code the html:

This part is very simple. Create an html unordered list with an li tag for each button. The list must have an individual id, as must each button. Something like this:

 
<ul id="nav_buttons">
<li id="button1"><a href="#"><span>Button 1</span></a></li>
<li id="button2"><a href="#"><span>Button 2</span></a></li>
<li id="button3"><a href="#"><span>Button 3</span></a></li>
<li id="button4"><a href="#"><span>Button 4</span></a></li>
</ul>
 

The span tags may seem un-necessary at the moment, however they will be useful when we come to hiding the text within each a link in the next stage. The great thing about this code is that it is really basic html that can be read by all browsers and search engine robots. If the user has images or CSS switched off in their browser they will still be able to use the navigation as basic text links.

Step 3 - apply the CSS:

So this is the part where we apply our image as the background for each link and reposition the background image appropriately. The first thing to do is set the style for the list itself:

#nav_buttons {
width: 320px;
height: 80px;
margin: 0;
padding: 0;
position: relative;
}
 
#nav_buttons li {
margin: 0;
padding: 0;
list-style: none;
position: absolute;
top: 0;
}
 
#nav_buttons li, #nav_buttons a {
height: 80px;
display: block;
}

The next step is to style each button setting the position of the button itself, and also the position of the background for each state:

/*set up the first button*/
#button1  {
left: 0; width: 80px;
}
 
#button1 a {left: 0; width: 80px;
background: url(example_sprite.jpg) 0px 0px no-repeat;
}
 
#button1 a:hover {left: 0; width: 80px;
background: url(example_sprite.jpg) 0px -80px no-repeat;
}
 
/*set up the second button*/
#button2  {
left: 80px; width: 80px;
}
 
#button2 a {left: 80px; width: 80px;
background: url(example_sprite.jpg) -80px 0px no-repeat;
}
 
#button2 a:hover {left: 80px; width: 80px;
background: url(example_sprite.jpg) -80px -80px no-repeat;
}
 
/*set up the third button*/
#button3  {
left: 160px; width: 80px;
}
 
#button3 a {left: 160px; width: 80px;
background: url(example_sprite.jpg) -160px 0px no-repeat;
}
 
#button3 a:hover {left: 160px; width: -80px;
background: url(example_sprite.jpg) -160px -80px no-repeat;
}
 
/*set up the fourth button*/
#button4  {
left: 240px; width: 80px;
}
 
#button4 a {left: 240px; width: 80px;
background: url(example_sprite.jpg) -240px 0px no-repeat;
}
 
#button4 a:hover {left: 240px; width: 80px;
background: url(example_sprite.jpg) -240px -80px no-repeat;
}

As you can see from this exampe it is a case of basic mathematics, adding 80px to the left for each additional button and subtracting 80px from the horizontal position of the background image each time, thus moving it to the left. For the hover states you must subtract 80px from the vertical position of the background image, thus moving it upwards.

The last thing is to hide the text (Button 1, Button 2, etc.) so that it doesnt display over the top of your button images:

#nav_buttons li a span {
display: none;
}

Final Thoughts:

The best way to explore this technique is to play with the numbers and view the difference in the results. I think you will find it to be a highly versatile method with many possibilities for creating single buttons, vertical or horizontal site navigation and more complex image mapping effects.

Thanks again to the writers of the two articles I found so useful in my exploration of this technique.

2 Responses to “Image mouseovers without javascript - CSS & Sprites”

Leave a Comment