CSS: list menu with changing background image on hover
21.04.2009 Tags: css,tutorial,Version française disponible ici! This trick will work with all modern browsers (yes, even IE 6).Imagine a list with a background that changes when moving your mouse over. The disadvantage of this way of doing it:
li a {
background: url(back.png) left top no-repeat;
}
li a:hover {
background: url(back-hover.png) left top no-repeat;
}
is that your background image back-hover.png is only loaded when you move your mouse cursor on the list element and not at page load. This causes a little lag while "hovering" the element.
The solution? Well, we could preload all pictures on page load with JavaScript for example, or we could create a big picture including back.png and back-hover.png and then "move" it whether we have the mouse cursor on it or not. We'll have a look at the second method right now.
Let's suppose we want an horizontal list with 3 elements, with a different background image for each list element. For example this: Example. First of all we need to draw our full background image:

We need to know the image's size (here 322 x 123) and the elements' sizes (~107 x ~62).
Let's begin with our CSS code and the main block:
#menu {
height: 62px;
background: url(hover-list-final.png) left top no-repeat;
}
Its height is the same as the list blocks' height.
The list looks like this:
#menu ul, #menu li {
margin:0;
padding: 0;
list-style-type: none;
}
#menu ul {
position: absolute;
height: 62px;
width: 322px;
}
#menu li {
float: left;
}
No padding or margin and no list style type.
Its height is the same as the list blocks' height and its width is the background image's width.
As we want an horizontal list, we need to define our li elements with a float: left.
Now let's have a look at the links:
#menu li a {
display: block;
height: 62px;
width: 107px;
color: #769712; //text color
text-decoration: none;
text-align: center;
}
#menu a:hover {
color: #fff;
background: transparent url(hover-list-final.png) top left no-repeat;
}
In this part, the important items are the display:block, height and width. Links will have the same size as the blocks. The rest is text styles and color.
Next we define the background image when hovering links. Firstly we declare the full picture for the a:hover element, then we'll create blocks for every link zone, delimited by the list elements and their size.
#menu a#menu1, #menu a#menu2, #menu a#menu3 {
display: block;
width: 107px;
}
And finally we need to create a class for each element, setting which part of the background image we'll display when hovering.
#menu a#menu1:hover {
background-position: 0px -62px;
}
#menu a#menu2:hover {
background-position: -107px -62px;
}
#menu a#menu3:hover {
background-position: -214px -62px;
}
The full CSS code:
#menu {
height: 62px;
background: url(hover-list-final.png) left top no-repeat;
}
#menu ul, #menu li {
margin:0;
padding: 0;
list-style-type: none;
}
#menu ul {
position: absolute;
height: 62px;
width: 322px;
}
#menu li {
float: left;
}
#menu li a {
display: block;
height: 62px;
width: 107px;
color: #769712; //text color
text-decoration: none;
text-align: center;
}
#menu a:hover {
color: #fff;
background: transparent url(hover-list-final.png) top left no-repeat;
}
#menu a#menu1, #menu a#menu2, #menu a#menu3 {
display: block;
width: 107px;
}
#menu a#menu1:hover {
background-position: 0px -62px;
}
#menu a#menu2:hover {
background-position: -107px -62px;
}
#menu a#menu3:hover {
background-position: -214px -62px;
}
And our HTML code:
<div id="menu">
<ul>
<li><a id="menu1" href="#">titi</a></li>
<li><a id="menu2" href="#">titi</a></li>
<li><a id="menu3" href="#">titi</a></li>
</ul>
</div>
It is also possible to have blocks with different widths. To perform that we need to set the width for each block:
#menu a#menu1 {
display: block;
width: AAApx;
}
#menu a#menu2 {
display: block;
width: BBBpx;
}
#menu a#menu3 {
display: block;
width: CCCpx;
}
#menu a#menu4 {
display: block;
width: DDDpx;
}
#menu a#menu5 {
display: block;
width: EEEpx;
}
and modify the displayed part of the background image:
#menu a#menu1:hover {
background-position: 0px -62px;
}
#menu a#menu2:hover {
background-position: AAA-BBBpx -62px;
}
#menu a#menu3:hover {
background-position: AAA-BBB-CCCpx -62px;
}
#menu a#menu4:hover {
background-position: AAA-BBB-CCC-DDDpx -62px;
}
#menu a#menu5:hover {
background-position: AAA-BBB-CCC-DDD-EEEpx -62px;
}
It is even possible to have different heights (for vertical menus for example). Same method as above =)




