RedVodkaJelly Logo

CSS Image Rollovers

POSTED AT 12:22 on 15th June 2007

I really hate having to use JavaScript for image rollovers as it seems messy, requires two separate images and can only degrade gracefully to nothing if the user has JavaScript turned off. In an attempt to find an all CSS method of achieving the same effect I discovered the following all CSS image rollover method this morning.

Example
 
Original Image
Full Image

CSS Code

  1. a.rollover {
  2.    display: block;
  3.    width: 30px;
  4.    height: 30px;
  5.    text-decoration: none;
  6.    background: url("email.jpg");
  7. }
  8. a.rollover:hover {
  9.    background-position: -30px 0;
  10. }

HTML Code

  1. <a href="#" class="rollover">&nbsp;</a>

All this does is show the first 30×30 pixels of the original image by default and then when you hover over the image we move the background image left by 30 pixels so the “active” portion of the image is displayed.

This gives the same effect as with a JavaScript rollover except users don’t need JavaScript and we only have to load a single image.

Works in all major browsers (FF 2, FF 1.5, IE 6, IE 7, Opera, Netscape, Safari 2, Safari 3 beta).

Trackbacks

Comments

  • tinny

    very smart trick, thanks for sharing

    Posted at 20:16 on 23rd June 2007
  • poki

    Thx a lot :)

    Posted at 16:18 on 24th June 2007
  • SubOne

    I’m actually very surprised there are still users that don’t know about this already.

    You can actually extend the effect even further. You can use a image with four different images in it for the “selected” effect. Simply set the body of each page to a specific class.

    News
    Services

    Then just specify the background position for selected elements like:

    .menu_item2 .menu_item3 {

    }

    Or if you have the use of a server side language like php you can remove the reference to a specific menu and save some excess css by specifying it server side and outputting a different class before the page is viewed.

    News
    Services

    Then just edit a rule for the menu_selected class. Using a single image for all four states: normal, hover, selected, and hover selected.

    You can style any tag with this functionality. For example, you can have a table without links, but a hover effect for each row (TD). In this way you can further distinguish the row the user is reading from the other rows. Although, it may be a good idea to save such an effect for things that can actually be interacted with. For example, a table row that can be selected and deselected without leaving the page (javascript required for selection functionality). Yet, with some creative design it can be very handy indeed.

    Note that IE6 and lower only allow a:hover and won’t recognize hovering over any other tag element. However, if you include an ‘htc’ file (basically javascript file which you can find online) as the css ‘behavior’ attribute then that’s fixed as well. I don’t remember if the ‘htc’ functionality works with javascript off. Also note that the ‘behavior’ attribute is not standard css and is only recognized by Internet Explorer, so use conditional IE comments to include a seperate css file for IE:

    Posted at 15:39 on 25th June 2007
  • SubOne

    Please edit my previous post so that the code is visible.

    Posted at 15:40 on 25th June 2007
  • SubOne

    and change ‘.menu_item2 .menu_item3′ to ‘.menu_item2 .menu_item2′ that was a typo. Thanks.

    Posted at 15:41 on 25th June 2007
  • Minja

    Great trick..thanks! I stumbled it.

    Posted at 19:34 on 26th June 2007
  • Matt

    of course this means you’ll have to have a different class for each image you want to roll

    or you could pass the image name to a javascript function that updates the ‘background: url’ param

    Posted at 11:21 on 27th June 2007
  • Erdal YILMAZ

    great approach saved a lot of my time thnx

    Posted at 21:31 on 30th June 2007
  • J. Bradford

    This is good, except for one problem. It’s not accessible. A person using a screen reader (ie: the blind…) would not be able to see this link because it has no text. The simple fix for this is to include text in the markup, but use CSS to make it invisible. Display:none seems like a good option, but screen readers often ignore anything with this attribute. The best option is to move the text of the link OFF the screen by setting left: -9999px. If you’ll notice, that would move the entire button off the screen, so instead, place the text within a span within the anchor markup. Then you can apply the positioning to a.rollover>span.

    This way, the rollover will remain unchanged, and screen readers will find the link text. Complete accessibility, with minimal non-semantic markup.

    Also, instead of using background-position: -30px 0, consider switching between background-position: left and background-position: right. If the background image is exactly double the width of the button, this should do what you want, and look a little cleaner.

    Posted at 12:50 on 13th July 2007
  • Jacob Wyke

    @J.Bradford: Thanks for the extra tips, I hadn’t really considered screen readers or text only versions but its really great advice.

    Posted at 13:31 on 13th July 2007
  • Matt Foster

    This is building off the idea of a css sprite.

    http://www.alistapart.com/articles/sprites

    Posted at 20:09 on 4th August 2007
  • Jacob Wyke

    Yeah it does build off the idea of a sprite, but I think it takes a different direction, because as I understand it the main purpose of a sprite is to keep the number of HTTP requests down as it only calls a single image and not multiple.

    But I would also highly recommend sprites to people and the article that you linked to is a fantastic resource.

    Posted at 00:32 on 5th August 2007
  • Jon

    Yeah this is a nice trick…
    IE6 (yeah it sucks) can flicker this nicely when you hover over it with your cursor.
    tools>internet options.
    click on the button for temporary internet files ’settings’ and set check for newer versions of web pages to every visit… you won’t even need a page refresh to see this.
    There are a couple of work arounds… if this bothers you (and it does bother my boss and our clients) set the out-state image as a background for an element containing your link… a quick google for ‘CSS flicker’ will show what I’m talking about.

    Posted at 16:06 on 4th September 2007
  • Estelle

    There are several issues with the code.
    In addition to it not being accessible (which has already been discussed), you are creating a block level element which really should be inline, or, perhaps acting as a bullet or icon before the link text.

    How about <a href=”email.html” class=”rollover”>email</a> - which is accessible

    and:

    a.rollover {
    width: 30px;
    height: 30px;
    text-decoration: none;
    background: url(’email.jpg’);
    text-indent: -3000px;
    *text-indent:0;
    color:rgba(0,0,0,0);
    display:-moz-inline-box;
    display:inline-block;
    overflow:hidden;
    }

    That will hide the text off the left side of the page for sited users, but enable screen readers to “see” it on the page. It will also create it as a seemingly inline element, so you can include it inline, but still give it height and width.

    Posted at 03:46 on 12th September 2007
  • Estelle

    I posted an entry giving more elaboration to the method explained above: Yet Another Image Replacement Method.

    Posted at 20:58 on 20th September 2007
  • Damjan Mozetic

    A great replacement for the classic javascript rollover.

    Posted at 22:20 on 29th January 2008
  • anwar

    hello, Estelle or anyone that can answer. I am new to css. I understand the concept of image rollover using css and a call sheet.But, Can someone just guide me a bit on how to repeat this sheet for 10 or 12 images. How would the css sheet setup look like, as well, as the html. you can visit my site to see the menu I am talking about. I currently am using old javascript. My page has not been optimized yet. and I know css will help with my menu loading time.

    Posted at 21:06 on 20th February 2008
  • anwar

    I thought I posted a question but it disappeared.
    I appreciate those who post so that new people to CSS can learn. I am curious to how you would repeat this code with several images for a verticle menu. what would the style sheet look like, as well as the html,? just display two items so I can get the basics of the coding and I should be able to repeat the rest for all my images….thanks greatly appreciated…
    Anwar

    Posted at 00:16 on 22nd February 2008
  • colickyboy

    I too am a noob with CSS. I got it to work in a horizontal menu with

    #navbar {height:141px; margin: 0px; padding: 0px;}
    #navbar li {list-style:none; display:inline;}

    and putting each menu item in an tag with , then adding float: left; to each menu item class.

    Unfortunately, this only worked in FF; didn’t work in either IE6 or IE7. Is there a way to get this to work in a menu on IE?

    Posted at 15:51 on 28th February 2008
  • colickyboy

    i got it to work in IE now. had to remove the height property in #navbar and add it (plus width) in #navbar a.classnum …man, is IE fickle…

    Posted at 17:27 on 28th February 2008
  • josh ventura

    AWESOME! Yes I was looking for this everywhere. How to add an image rollover when in the you just slap the [ ]. thanks!
    ___
    http://www.joshventura.com

    Posted at 11:47 on 2nd March 2008

Leave a Comment