Feed Sign in with OpenID OpenID

Simon Willison’s Weblog

Javascript free rollovers

I’ve talked about image rollovers on this site before, but I’ve never seen a technique I like half as much as Pixy’s Fast rollovers, no preload needed. Like all good techniques, it’s so simple I’m surprised no one has thought of it before. The trick is that a single image is loaded containing the different rollover states, then positioned as the background of a fixed pixel size link element in such a way that only one of the states is shown. The :hover style simply changes the offset of the background, revealing the secondary (or even tertiary) state.

This is Javascript free rollovers by Simon Willison, posted on 10th September 2003.

View blog reactions

Next: PostgreSQL Performance Optimisation

Previous: Andy in the Garden

22 comments

  1. The link to Pixy's site brings up a 404... :-(

    Bob - 10th September 2003 18:10 - #

  2. The URL worked fine for me. This is a cool use of CSS, but it suffers from the same drawback as most background switching: if the visitor has his default text size larger than intended, or if he increases text size once he arrives on the page, the background image won't display as intended. In the case of the example, bumping up text size to 200% reveals the previously hidden portion of ALL the background images. Of course, 200% is a fairly extreme magnification, but it's possible that vision-impaired visitors could use it, if the original text is deemed too small. Another accessibility issue rearing its head...

    Eric - 10th September 2003 18:47 - #

  3. In response to Eric's concern, what I did was put the different link states side by side, horizontally, rather than stacked vertically. With this arrangement, the alternate link states stay hidden pretty much no matter how much text size is increased. The site I've done this on is http://www.offemp.com (some areas are still works in progress).

    Warren - 10th September 2003 19:01 - #

  4. Warren, I didn't look at your CSS or source coding. I assume that for your technique to work, the container has to be fixed-width. Otherwise, it seems that you'd have the same problem as the text expanded horizontally.

    Fixed width containers pose their own special challenges when coupled with resizable text.

    Eric - 10th September 2003 19:39 - #

  5. Eric, you're correct about the container needing to be of a fixed width, although that posed no problems with this particular layout (involving a vertically-oriented navigation scheme). I used the "text-indent : -10000em;" method (the creator's name escapes me at the moment) to hide the text, and all that happens upon increasing the text size is the vertical spacing between links increases, although not enough to hurt the layout. I can certainly see instances wherein this method wouldn't be feasible, but in this case it was just the ticket.

    Warren - 10th September 2003 20:30 - #

  6. I really like Pixy's trick, all smart CSS solutions for that matter.

    There is a downside to this solution though. It (obviously) requires you to download all the images, or actually a 'larger, combined' image. When you have a lot of navigational links, all images would be loaded, instead of just the one requested. I know this might not be a big issue with people on DSL or cable... But it would increase the download-time for the complete page...

    When I browse some website I often use only a few navigational links. Isn't this just 'moving the problem to another area'?

    (It is ofcourse much better than Javascript rollovers!)

    Dave - 10th September 2003 21:48 - #

  7. Regarding the method: The first i've heard of this method was from pixy but i was recently looking at creating my own themes in mozilla and found that the mozilla browser is using this method already with it's XUL and CSS. I don't know if it was implemented after pixy went public with this method but I thought it was worth mentioning.

    Josh - 10th September 2003 21:50 - #

  8. Dave, I think it depends on how the method is used. If you are creating all the states of the button for each button the page then yes the downloaded images become unnecessary. But if you use simple designs for each of the links states, and it's being used for all the buttons in your navigation then I would think the download would be faster. I'm not sure if i was clear in what i just wrote but i hope my thought is understood. Most sites create seperate images for each button and each state of the button. This method would definitely improve download times as long as used properly. But that's just my $0.02, -Josh.

    Josh - 10th September 2003 22:00 - #

  9. Dave, think about this from the other end: you save one request *if* you hover ... and a combined image is smaller than two separated. :)

    Thomas Scholz - 11th September 2003 02:40 - #

  10. You also save on all the javascript required to preload and rollover ...

    Rob Ballou - 11th September 2003 04:10 - #

  11. From My P.O.V This Is A Hack.

    The CSS Spec Defines _Direct_ Method Of Contolling Hovering Over An Object - :Hover Selector. And It's The Browser's Task To Make A Decent Implementation Of 'Hovering' Metaphor. I Mean It's Not That Hard For A Browser To Automatically Preload Background-Image Specified In :Hover CSS Rules.

    This Method Is A Workaround For The Weakness Of Contemporary Browsers' Implementation Of Hover. This Is The Same Old Way Of Writing For A Browser, Not For A Standard. That's Why I'm Not So Impressed With It. If Designers Again Invent Workarounds For Everything Then Why Browser Makers Should Bother Implementing It Better?

    Maniac - 11th September 2003 08:50 - #

  12. Josh, I agree with you on that. If you use just 2 images ('normal' and 'hover' state) and continue to use only 'instances' of those two...

    Thomas, it would require more requests while the whole page is loading, I'm actually not sure if 1 combined image is smaller then 2 seperate ones, seperately they load faster and you would notice the effect sooner... So I guess it depends on how much different images you use, using a lot of different images actually could increase the overall loading time. Especially when most of those aren't used because they are not 'hovered'...

    Maniac, how exactly would current browsers preload the hover-state-images (defined in a CSS sheet)??

    Dave - 11th September 2003 09:40 - #

  13. I was converting someone else's layout to use xhtml/css and as a handy excuse to try out this technique as well as the negative text-indent one which was mentioned on phark.net. All is well on Firebird, but IE6 seems to reload the whole image on :hover, creating a nasty flickering effect:

    http://www.dti.barrysworld.net/web/cellison/

    insin - 11th September 2003 09:55 - #

  14. I noticed the same flickering as Insin with IE6 :/ But If you access the page from your cache this works great ! :p

    Here's a small demo (Icelandic) I made the other day using this method.

    Andri Sigurðsson - 11th September 2003 13:36 - #

  15. Dave, I had images in mind which contain two pictures: one for the "normal" state and one for "hover". Thus, the absolute number of request is the same, with or without "hover". Combined images are smaller than separated because you need just one set of meta-information for "both". But indeed it depends: if your images have a very different range of colors, compressing is less effective... I still think, when the readers won't use the links, the page has a lot of other problems than such a marginal one like hover images...

    Thomas Scholz - 11th September 2003 16:32 - #

  16. Those experiencing flicker in IE6 - try turning off IE's checking for a new file every time it's displayed.

    Tools > Internet Options > General > Settings (under Temporary Files) > check 'Automatically'

    Note that most of the populace browses with this already set properly, so it shouldn't hinder anyone from using this technique. Only developers need it turned on.

    Dave S. - 11th September 2003 21:03 - #

  17. Andri, your demo works very well in IE6, Mozilla and Opera, but fails badly in IE 5.5. I notice your CSS includes some hacks for IE 5.5, but it seems they're not having the desired effect. Do you think it could be improved?

    francois - 12th September 2003 09:52 - #

  18. Andri, you want to take a look at your version in IE5,5. I can see you've tried to implement an exclusion for IE5,5, but the height of each <li /> is too big here and looks rather messy (and I can see the text for each item, which makes the menu very untidy).

    Very elegant solution, though, I like it!

    Of course, I prefer no images for navigation at all, myself. But I'm just a geekboi with no sense of æsthetics… ;o)

    Owen Blacker - 12th September 2003 09:55 - #

  19. HI there, I am new to the css layout, and trying to get to grips with iot for most things now. However, I wondered if someone could offer comments on a site I have been working on, with a lot of CSS (the most I've used), in particular the navigation and Flash movie on the home page. I have tried to preload the rollovers as small images at the bottom of the page, but noticed that there was a bit of a delay on a dial up connection. Any help and advice is greatly appreciated. Cheers Andy in the UK

    Andrew Downie - 12th September 2003 16:09 - #

  20. Francois, Owen, thanks for the tip! I updated the demo and it should look ok now. It turned out the exclusion was doing the trick but I had typed in the wrong height :)

    Andri Sigurðsson - 12th September 2003 22:33 - #

  21. Andri: excellent job on the demo! i'm planning on using this method for my own web site now because of it. ;)

    grimby - 6th January 2004 11:33 - #

  22. Pixy's new URL: http://wellstyled.com/css-nopreload-rollovers.html

    sandra - 14th December 2005 23:20 - #

Comments are closed.

Previously hosted at http://simon.incutio.com/archive/2003/09/10/jsFreeRollovers

A django site