CSS rollover buttons, sans JavaScript

Written May 31, 2009. 5 comments.

While scoping for a new designer I recently read through over 50 resumes and consequently looked at over 50 online portfolios. What struck me as frankly surprising (shocking) was the high number of designers who still use oodles of JavaScript to create a simple image hover effect, usually in the navigation.

I have a simple rule: If it can be accomplished with CSS, then do it with CSS. Unless it breaks standards or semantics of course. So here is my simple tutorial preserved for prosperity in the hope it will one day reach the right people.

How it works

We are going to use a single image to create 3 buttons states: default, hover and active. Basically we are going to position the background image for each state with CSS. The image (button.gif) I’ve created for this tutorial looks like this:

button

The dimensions of this image are critical, in that all 3 states need to be the exact same width. Each button state in this example is 120 pixels wide, which means we also have to make it known in the CSS.

Start with a simple menu list like…

<ul id="menu"> 
<li><a href="">Item 01</a></li> 
<li><a href="">Item 02</a></li> 
<li><a href="">Item 03</a></li> 
</ul>

…with this CSS.

#menu li { 
list-style:none; 
text-align:center; 
float:left; /* Remove this float if you prefer a vertical menu */ 
}

#menu li a { 
width:120px; 
height:30px; 
padding:10px 0 0 0; 
display:block; 
background-image:url(button.gif);  background-position:left; 
text-decoration:none; 
color:#fff; 
}

Notice we have positioned the background image left for list items which are 120px wide, which means only the left (blue) part of it will be visible.

Changing states

Now we want to change the position of the background image for 2 more states, hover and active. Add this CSS:

#menu li a:hover { 
background-position:center; 
}

#menu li a:active {  
background-position:right; 
}

Now when you hover over a menu item the background position shifts to the center showing only the green section, and when the mouse is active the background position shifts to the right to only show the orange section.

Too easy huh? Test it out for yourself here.

Why one image and not three?

The exact same effect can be achieved with 3 separate images, but each would have to be referenced accordingly in each of the 3 CSS states, but using a single image is better because it means you only have one http request as opposed to 3.

button_states.zip (8k)

Who is That Web Guy?

Michael is a veteran web designer / developer / usability evangelist, practitioner of W3C guidelines, and currently head of the web dev unit at Stormbox, a branding and creative communications agency located in Perth, Western Australia.

5 Responses to CSS rollover buttons, sans JavaScript

  1. Davo says:
    A good lesson to those still using MM Script
  2. @todayinart says:
    Another one that I like to use, especially when I have a cool background, is to change the opacity of the menu item.

    #menu li a:hover {
    /* for IE */
    filter:alpha(opacity=75);
    /*for IE8 – though it seems to work without the quotes still*/
    filter: “alpha(opacity=75)”;
    /* CSS3 standard */
    opacity: 0.75;
    }

  3. Greg Molyneux says:
    Great little tip Mikey. I do my best to avoid Javascript where possible, but I’m still quite new at design some I’m just trying to hone my CSS skills a little bit at a time while focusing on doing things the right way.

    I really dig(g) the new site by the way!
  4. owen says:
    I’m using this one! Cool trick to remove the messy Javascripts. Hope you also include drop down menu tutorial. Thanks
  5. Edwardo says:
    I wasn’t even aware people still used javascript for a simple effect like that. Liking your site very much web guy.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

+ 9 = twelve