CSS image rollovers

By Michael Gakuran | | Design & Web | 10 Comments |

You may have noticed in the past few weeks some small changes on the website. The main update was in giving my header links rollover images, but this was not quite as simple as in the old days of HTML and Javascript. Now there are all sorts of usability issues and web standards to conform to! I am indebted to JohnJamesJacoby for all the help and advice in sorting it out. It was a great learning experience! So, continue reading this post for an explanation of the not-so-secret CSS image rollover technique. It’s quite sneaky…

I imagine that most people are aware of image rollovers. Quite simply, the picture changes when you hover the mouse cursor over an image that has a rollover effect. This can be done quite easily with a bit of Javascript, but the reader must have Javascript enabled in their browser in order for it to work. A better way to achieve the same effect is through CSS. All the code you need goes in one stylesheet, and you only use one image to make rollovers for as many images as you need! Seems impossible, right? Read on –>

Header

In traditional rollover effects, you would just substitute one image for another. So when the reader hovers their mouse of the image, it changes. The problem with this is, when the reader hovers over the image, the new image must be loaded by the browser. This results in a slight flickering between the change. It doesn’t sound like much, but it can really detract from a website’s feel, and more importantly, it can sometimes take longer to load the new image than expected. This results in a period of time where no image at all shows!

In order to solve this problem, all of the rollover states for images are created in one image. This image is then repositioned when the user hovers his or her mouse on it. So in effect, the image itself is not changing, only the position is. Check out my header image:

Knowing Nothing title

When you roll over it, the image shifts 297 pixels to the left (297 is half of the image width). The right-hand side of the image is the same as the left, only with a 75% transparency applied to it. So the reader sees the image becoming ‘transparent’ when actually all that is happening is that they are seeing an entirely separate part of the same image.

Here is the code in my stylesheet for the header:

#logo {
float: left;
padding: 0;
width: 762px;
height: 300px;
margin: 0 auto;
position: absolute;
}

#logo ul{
list-style: none;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}

#logo ul li{
display: inline;
margin: 0;
padding: 0 0;
}

#logo ul li a{
text-decoration: none;
color: #003300;
border-bottom: 0 none;
}

#logo a{
overflow: hidden;
border-bottom: 0 none;
}

#logo a:hover{
overflow: hidden;
border-bottom: 0 none;
}

#logo .knowingnothing a{
position: absolute;
top: 74px;
left: 81px;
width: 296px;
height: 123px;
background:url(images/kn-header-mouseover.png) 0 0 no-repeat;
}

#logo .knowingnothing a:hover{
background:url(images/kn-header-mouseover.png) -296px 0 no-repeat;
}

#logo span {
position: absolute;
height: 0;
width: 0;
overflow: hidden;
}

The things to note here are that I have made a an id and a class for my logo (both may not be necessary) and I have positioned it absolutely. You can see for the knowingnothing a:hover I have told it to shift the image by 296 pixels left (indicated by the minus sign). This lines up the image and makes it look as though it is merely changing transparency rather than actually moving.

Note the span class. This is because when making a hyperlink in the header.php file, it is necessary to have something to link to. Because I have set my header logo to be a background image, the hyperlink would effectively become empty. So I type the text ‘Knowing Nothing’ into the hyperlink to display the link. But now this text will show up on top of my image. To stop this, I use the span class in my stylesheet with width and height at 0 and overflow set to hidden. In my header.php hyperlink, I would use CSS span tags around the ‘Knowing Nothing’ text. This hides the text from view, but still allows the hyperlink to work correctly and display my background image.

Why not just put the image into the hyperlink? You could do this, but then you have more work to do maintaining your website. The benefit of doing everything in the stylesheet is because it makes it much easier to change things later on.

Menu

Next up, the menu:

This was a little more tricky, and there may be better ways to achieve the same effect as I have. I am but a student and CSS is not my forte. Here’s my menu image:

Knowing Nothing menu

And here is the code in my stylesheet:

#menu{

float: left;
padding: 0;
margin: 0;
font-family: Georgia, sans-serif;
font-size: 25pt;
font-weight: bold;
width: 762px;
height: 100px;
position: absolute;
top: 300px;
}

#menu ul{
list-style: none;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}

#menu ul li{
display: inline;
margin: 0;
padding: 0;
}

#menu ul li a{
text-decoration: none;
color: #003300;
border-bottom: 0 none;
}

#menu a{
overflow: hidden;
position: absolute;
left: 50px;
top: 28px;
height: 43px;
width: 655px;
background: url(images/kn-menu.png) top left no-repeat scroll;
border-bottom: 0 none;
z-index: 40;
}

#menu a:hover{
overflow: hidden;
border-bottom: 0 none;
}

#menu .home a{
width: 125px;
float: left;
z-index: 50;
}

#menu .home a:hover{
background:url(images/kn-menu.png) 0 -42px no-repeat;
}

#menu .about a{
width: 275px;
float: left;
z-index: 49;
}

#menu .about a:hover{
background:url(images/kn-menu.png) 0 -42px no-repeat;
}

#menu .goodies a{
width: 465px;
float: left;
z-index: 48;
}

#menu .goodies a:hover{
background:url(images/kn-menu.png) 0 -42px no-repeat;
}

#menu .topposts a{
width: 655px;
float: left;
z-index: 47;
}

#menu .topposts a:hover{
background:url(images/kn-menu.png) 0 -42px no-repeat;
}

#menu span {
position: absolute;
height: 0;
width: 0;
overflow: hidden;
}

For those not very familiar with CSS (which includes me), this might seem daunting. Basically I have defined an id (menu) and 4 classes (for my header links: home, about, goodies and top posts). I then do the same thing as for the header logo and move my image, but I move it vertically this time. The other important part here is the z-index. There are problems with this in IE6 (although I think it still works, just barely).

The higher the z-index, the higher on the page the element shows. So a z-index of 50 shows above 1-49 and so on. The benefit of this is to position absolute elements on top of one another. In my case, when I move my image up 42 pixels for the ‘goodies’ button, the ‘home’ and ‘about’ buttons also show as having changed. But if I set them to a higher z-index than ‘goodies’, then I will only see the change on the ‘goodies’ button. Although the whole image is actually shifting, the reader cannot see it because ‘goodies’ is a lower z-index than ‘home’ and ‘about’, hence the changes for those two buttons are hidden. Similarly, for ‘top posts’, its z-index is lower than ‘goodies’, so goodies will not change when the user hovers over the ‘top posts’ button.

This may be overly complicated and there may be a simpler method. If so, please tell me! I am very interested in learning more.

Also, check out these links for more help on relative and absolute positioning in CSS and also a cool program for testing websites in Internet Explorer:

Barely Fits CSS Positioning

Browser testing in IE

You can directly view the WordPress support topic where all this was discussed here. And please drop by John’s site as well ^_^.

10 comments on “CSS image rollovers
  1. Mike says:

    Yea, cross browser problems suck! The times I’ve thought I finally nailed a design only to have IE6 (and sometimes even IE7!) throw a hissy fit is beyond remarkable.

    The rollover was a good learning experience. The site is undergoing more changes right now, so expect a heft change sometime soon. Not a full re-design, but rather significant all the same! ^^

  2. Mike says:

    Yea, cross browser problems suck! The times I’ve thought I finally nailed a design only to have IE6 (and sometimes even IE7!) throw a hissy fit is beyond remarkable.

    The rollover was a good learning experience. The site is undergoing more changes right now, so expect a heft change sometime soon. Not a full re-design, but rather significant all the same! ^^

  3. Satoshii says:

    Whenever I write code for a website there is always, *always* some cross browser problem. It doesn’t work in IE or you haven’t put this decelration in for firefox. Sometimes I just want to chew my own head off!! Thats why it takes me so long to do anything. One of these days, my site will be there like yours is. I can only hope. haha. *cries*

    btw good job on the rollover. Much more uber fancy than I would of done it, but then again I suppose yours works, lol *QQ some more*

  4. Satoshii says:

    Whenever I write code for a website there is always, *always* some cross browser problem. It doesn’t work in IE or you haven’t put this decelration in for firefox. Sometimes I just want to chew my own head off!! Thats why it takes me so long to do anything. One of these days, my site will be there like yours is. I can only hope. haha. *cries*

    btw good job on the rollover. Much more uber fancy than I would of done it, but then again I suppose yours works, lol *QQ some more*

  5. Mike says:

    Hey Jacob. Thanks for the comment! It’s all down to your help really ^_^

  6. Mike says:

    Hey Jacob. Thanks for the comment! It’s all down to your help really ^_^

  7. Wow awesome write-up! Thanks again for the kudos and good luck with your site! It really is coming along nicely!

  8. Wow awesome write-up! Thanks again for the kudos and good luck with your site! It really is coming along nicely!

Leave a Reply

Your email address will not be published. Required fields are marked *

*