Slightly more complex sprites
Welcome to part 2 of the 3 part sprite series. If you missed the first part then go check out my ’Simple sprites’ post.
So what happens when you’ve got a menu based on say a map where you might have a bit of an overlap with your sprites? If you create a sprite the traditional way then you will notice that when you hover on your link there will be a slight hover on another link. Let me demonstrate. Here’s what we want to have:

If we were to use a normal sprite it would look like this:

As you can see there is a fair bit of overlap. This results in the links having an unintended effect on hover. This is because links are rectangular which means that the background image for each menu item goes into other links as can be seen here:

The overlap of the menu items, when hovered, will result in the most hideous of effect of either the surrounding menu items being partially hovered; or the menu item you are hovering over only partially having the hover effect. It looks extremely bad and quite unprofessional. Here’s how ours would look if we stuck with the simple sprite:

As you can see the menu items above and below the one we’re hovering over look partially hovered and consequently kinda crap. The way we get around this is by extending our sprite image. What we need to do is separate the hover states of the overlapping menu items so that each hover state on the sprite image is surrounded by the off states of the other menu items. This way when you hover over a link you wont get rubbish that comes with using a simple sprite for this situation. Here’s what our sprite image will now look like:
Now we have three of each menu item. One with the hover state and two without. Making the sprites work now is just a simple matter of changing the background position on hover to whatever is needed... Well maybe not quite that simple. First we need to position relative the ul and make our li’s position absolute. The width and height of our ’a’ tags need to cover all visible parts of our menu items and we’ll overlap them by positioning them and giving a higher z-index to your top level menu items. Since we’re positioning our links we’ll have to give our ul a set width and height which will be the width and height of the off state part of our sprite image.
Now we need to apply our sprite image as a background for the ul. This is because we will be using this as our off state instead of the background in the li. since everything needs to be together we don’t need to worry about paddings and margins on the li’s or ’a’ tags so applying the background to the ul is fine and everything will line up. For more complex sprites our default link background position will be something like ’-1000px top’ to make sure that there is no background for the off state of the li. We then change the hover background for each link to be what we need. By doing it this way instead of having the off state background on the li we don’t have to worry about the higher z-indexed off state backgrounds on li’s covering the other menu items as this will bring us back to our original problem. Here is an example of the new CSS for this type of sprite:
#nav { position:relative; overflow:auto; background:url(images/sprite.png) no-repeat; }
#nav li { margin: 0; list-style: none; display: block; position: absolute; left: 0; top: 0; }
#nav a, #nav a:link, #nav a:visited { text-decoration: none; border:none; display:block; background:url(images/sprite.png) no-repeat left 500px; width: 100px; height: 30px; line-height: 1px; font-size: 1px; overflow:hidden; text-indent:-999px; }
#nav a:hover { text-decoration: none; }
#nav #nav1 { z-index: 222; }
#nav #nav1 a { width: 150px; height: 34px; }
#nav #nav1 a:hover { background-position: left -134px; }
#nav #nav2 { top: 34px; z-index: 111; }
#nav #nav2 a { width: 134px; height: 35px; }
#nav #nav2 a:hover { background-position: left -302px; }
#nav #nav3 { top: 64px; z-index: 222; }
#nav #nav3 a { width: 145px; height: 37px; }
#nav #nav3 a:hover { background-position: left -197px; }
#nav #nav4 { top: 99px; z-index: 111; }
#nav #nav4 a { width: 138px; height: 36px; }
#nav #nav4 a:hover { background-position: left -367px; }
Now to the issues of these and more complex sprites. If you have a menu and you want to highlight the page that you’re on while still having your usual hover effects it starts to get very tricky and will require another level on the sprite. The next level will require a few sets with two menu items in sequence with their hover state. Here we have the sprite that we would need for this. The problem now is that we also need to use a bit of javascript in order to make sure that, depending on what page we’re on and what we hovering over, the correct menu items have their hover state. In the end a huge amount of time will be taken to create the sprite and even more used to to set all the correct background positions for off, hover and page highlighting. In my opinion if is definitely more time effective and feasible to make small alterations to the design in order to use a simple sprite or simply be happy with not highlighting the current page. Sometimes cutting down a little on the specky stuff can be the better business decision. Here’s the final menu: