Image Sprite Navigation With CSS

This entry was posted on Monday, October 22nd, 2007 at 9:20 pm

Why slice a new image for each item in a navigation when you can use the same image for all of them? If you’re thinking you can’t do that without sacrificing rollovers, think again. By creating a navigation using an image sprite, you can have a complete navigation, rollovers and all, by only using one image.

What is an image sprite?

Image sprite originated from old nintendo games – what developers had to do to keep the game from having to load a new image each time a different character entered the screen was store all of the images into a grid – once they had this grid they could call different sections of it and tell it to display it on the screen. The same big image was loaded one time, from then on different sections were called and displayed on the page.

How to use image sprites to create a CSS navigation

What we are going to do is copy the old image sprite technique used in video games, and apply it to our CSS. How you ask? We can do this in by off-setting the background position of each list item in our nav. Let me break this down step by step to help understand this concept.

1. First thing I did was create a very simple image for my nav bar, you can make one the same as mine if you are following along or if you’d like, it should be clear enough to make your own.

Sprite Nav Without Hover State

2. Once I was satisfied with my image, I exported it as nav.jpg. Once you have that image exported, change something on your navigation, you can change the color of the background, underline it, drop shadow or anything you want as long as the text for the titles don’t get too close to each other where they are interfering. Once you have made these changes, export the image again but call it: nav-over.jpg.

Sprite Nav Hover State

3. Now that we have two images, we need to combine them together into one image. Open both of the images, with nav.jpg selected, go to the Image > Canvas Size… option. Select the top of the image as the anchor point and change the units of measure to percent. Now make the height 200% and click ok.

Now our nav.jpg is in the top of its window, with blank space beneath it.

Sprite Nav Canvas Resized

4. With Snap turned on, drag nav-over.jpg into the same window as nav.jpg. Place it exactly below it so it fits perfectly into the newly created space. Our new image should look something like this.

Sprite Navigation Combined

5. Now resave nav.jpg with both of the images combined, this is going to be the image we use for our navigation.

Once you have the image saved, we can start applying HTML and CSS to get this sucker working.

6. First we need the HTML, here we can make a simple unordered list that includes a different li for each of the buttons we created in photoshop (in this case 4.)

<ul id=”nav-example”>
<li id=”nav-example-01″><a href=”#”><span>Blog</span></a></li>
<li id=”nav-example-02″><a href=”#”><span>Portfolio</span></a></li>
<li id=”nav-example-03″><a href=”#”><span>Resume</span></a></li>
<li id=”nav-example-04″><a href=”#”><span>Contact</span></a></li>
</ul>

7. What we have now is an unordered list with 4 different button list items that each match a certain button on the navigation. The reason there is a span tag with the text inside it is because this way search engines see the text, not just an image. We will end up turning the span to display:none so the text doesn’t show.

This is still viewed as white hat SEO because the text matches the same as the text in the images. Be careful because you can get flagged for putting different content in the hidden fields if it doesn’t match the text on the background image.

8. Here is the final CSS of the image sprite navigation, the final example is at the bottom of the post, I’ll break each section of the CSS down piece by piece:

#nav-example {
background:url(“/images/nav-final.jpg”) no-repeat;
width:490px;
height:40px;
margin:0;
padding:0;
}

#nav-example span {
display: none;
}

#nav-example li, #nav-example a {
height:40px;
display:block;
}

#nav-example li {
float:left;
list-style:none;
display:inline;
}

#nav-example-01 {
width: 98px;
}
#nav-example-02 {width: 131px;}
#nav-example-03 {width: 123px;}
#nav-example-04 {width: 138px;}

#nav-example-01 a:hover {background:url(“/images/nav-final.jpg”) 0px -40px no-repeat; }
#nav-example-02 a:hover {background:url(“/images/nav-final.jpg”) -98px -40px no-repeat; }
#nav-example-03 a:hover {background:url(“/images/nav-final.jpg”) -229px -40px no-repeat; }
#nav-example-04 a:hover {background:url(“/images/nav-final.jpg”) -352px -40px no-repeat; }

9. The first part is the sizing and background image of the nav bar, the reason we set the height to 40px is because that is how big my original nav.jpg was before I combined it with the nav-over.jpg. This way only the top half of the image displays.

10. The #nav-example span is set to display none, this is what is going to hide the text of each list item. (Remember be careful not to try to hide keywords in these hidden fields, search engines will penalize you.)

11. #nav-example li, #nav-example a {height:40px; display:block;} – What this line is doing is displaying each list item and link to display block with a height of 40px. This makes sure that each link on the navigation is the same size. The reason it is displayed as block is so we can change the size of it, if it wasn’t we couldn’t change the width and height of each link.

12. #nav-example li {float:left; list-style:none; display:inline;} – The float:left is making it so each list item moves to the left side of each li below it, display inline makes sure they display in a horizontal line. List-style: none changes the li’s to not have a bullet next to them, sweetness.

13. #nav-example-01 {width: 98px;} – This is setting the width of the first button “Blog,” if I wanted to start this button 10px off the left side of the #nav-example I could do it by setting margin-left: 10px. The next couple lines are setting the width of each individual link, this way the 4 link widths add up to the total width of my main navigation(you can measure each link by either making guides or selections). Now comes the cool part.

14. What we have to do is set the a:hover state, the way the background is offset on each hover is (horizontal number of pixels) (vertical number of pixels.) Since we have a horizontal nav bar, the vertical number of pixels to be offset is going to be the same for all of them. For the first one it is going to be 0px -40px, 0px because the background image only needs to come straight up to the top left of the nav, so what we do is tell it to go 0px left or right and -40px vertical, a negative integer brings the background UP. This shows the bottom part of the sprite nav, and since we set the width of the li’s it only shows on the particular li we are hovering over.

15. To get the next number we take the width of the nav-example-01 and subtract if from the previous horizontal offset number(which was 0 in this case.) 0-98 = -98px, I’m a math genius. Now we can put this in for the next li, nav-example-02 a:hover will be -98px -40px no-repeat.

16. We do the same for the next one now, -98-131=-229px. Now the offset for the a:hover on nav-example-02 is -229px -40px. This is moving the top left corner of the li background image to the correct position.

17. Normally if you were to put the a:hover’s background image to nav-final.jpg, whichever li you were in it would show the new background image in the top left corner of it, this is why you have to offset the horizontal value to get the correct section where you want it.

18. Now if you do the same process for calculating each button you’ll end up with the same numbers I do, unless you have your own nav with more buttons or different width, then you’re on your own at this point. Once all the CSS is laid out correctly your nav should function like this one below.

Follow me on Twitter and ask your questions there to get faster answers, it’s not as easy for me to respond via the blog. Thanks!

184 Comments:

Leave a Comment