Accessible Image-Tab Rollovers

I recently implemented a new navigation system for Fast Company and thought it’d be useful to document the process.

The Problem

We needed to fit more items into FC’s top navigation. We ran out of room. Previously, this was handled by a simple, styled unordered list. But at a window resolution of 800×600 there wasn’t enough additional horizontal space to add even one more item using the current design.

The Solution

I choose to combine and modify Pixy’s brilliant Fast Rollovers and Stuart Langridge’s accessible image replacement technique to create accessible, Javascript free, image-tab rollovers.

How does it work?

The XHTML: One List to Rule Them All

I wanted to continue to use a simple unordered list for the navigation in the markup. Much has already been said about using lists for navigation, here and elsewhere. They’re compact, lightweight and accessible to text browsers, screenreaders, PDAs, phones, etc.

Here’s what the list looked like originally (I’ve deleted some of the actual items to make it more convenient to demonstrate):

<ul id="nav">
<li><a href="/" class="selected">Home</a>&lt/li>
<li><a href="/guides/">Guides</a>&lt/li>
<li><a href="/magazine/">Magazine</a>&lt/li>
<li><a href="/articles/">Archives</a>&lt/li>

Nice and simple. Now let’s add a unique id to each li so that we can do some fancy stuff with it (namely, replace the boring text with stylized tabs):

<ul id="nav">
<li id="thome"><a href="/" class="selected">Home</a>&lt/li>
<li id="tguides"><a href="/guides/">Guides</a>&lt/li>
<li id="tmag"><a href="/magazine/">Magazine</a>&lt/li>
<li id="tarchives"><a href="/articles/">Archives</a>&lt/li>

Now we’re ready to create some tab images.

One Image, 3 States

The essence of Pixy’s Fast Rollovers involves creating one image for each navigation item that includes normal, hover and active states stacked on top of each other. Later, we’ll use CSS to change the background-position to reveal each state at the appropriate time.

fig. 1
Figure 1.1

Figure 1.1 on the right shows an example image that I’ve created and used for Fast Company’s new navigation. Each state is 20px tall with a total image height of 60px. The top 20px is the normal state, the next 20px shows the hover state and final 20px shows the active state (which is also used for the “you are here” effect). There are similar images for each tab we’d like to use.

Using one image for each state allows us to toss out ugly Javascript and instead make use of simple CSS rules for hover effects. This is good. It also eliminates the “flicker” effect that other CSS methods suffer from, where separate on/off images are used. This is good. We also don’t have to pre-load any additional images. Again… this is good.

The CSS: This is Where the Magic Happens

First we’ll set up the rules that all navigation items will need. This will save us from writing duplicate rules for each tab. Then we’ll add a separate rule for each list item id, giving the li it’s own background-image and width — the only two variables that will be different for each tab.

The CSS goes something like this:

#nav {
margin: 0;
padding: 0;
height: 20px;
list-style: none;
display: inline;
overflow: hidden;
#nav li {
margin: 0;
padding: 0;
list-style: none;
display: inline;
#nav a {
float: left;
padding: 20px 0 0 0;
overflow: hidden;
height: 0px !important;
height /**/:20px; /* for IE5/Win only */
#nav a:hover {
background-position: 0 -20px;
#nav a:active, #nav a.selected {
background-position: 0 -40px;

This essentially turns off padding and list styles, makes the list horizontal and hides the text that’s between each hyperlink in the list. Notice the :hover and :active rules. These are generic for every a element within #nav so that we don’t have to repeat those particular rules for each item.

I’ve also assigned a “selected” class to a tab that I wish to highlight permanently, signifying which section of the site you are currently on. This is shared with the :active state.

You may also notice that list-style: none; and display: inline; are repeated in both the #nav and #nav li selectors. This was to keep IE5/Win happy. In a perfect world, declaring this once for #nav would be perfectly sufficient. That’s not the case, of course.

Next, we’ll add the rule for each id and assign it’s background-image and width. Here’s an example:

#thome a  {
width: 40px;
background: url(home.gif) top left no-repeat;

There’s a similar declaration for each tab needed.

The Results

fig. 2
Figure 1.2

Figure 1.2 shows the resulting tabs in normal, hover and selected state. To see it all working in action, check out the working example with sourcecode, or better yet, the real-world implementation at

Why use it?

  • It’s lightweight: Just an unordered list in the markup.
  • It’s accessible: Using Stuart’s method, we can insure screenreaders will read the text links.
  • No Javascript: We don’t need to pre-load or create multiple images for each state. We also don’t need extra Javascript to control hover effects. Thanks, Pixy.
  • It’s stylized: Fitting hypertext into defined areas can be tricky, this allows for using stylized images.

But Wait, the Text Doesn’t Scale!

Following a great suggestion from Doug Bowman, and in response to legibility issues and the inability to resize image text, I went a step further and created second set of tab images with larger text labels. I could then override rules on the exisiting “medium” and “large” alternate stylesheets. The alternate styles are activated using Paul Sowden’s Stylesheet switcher.

An example of the overriden rule looks almost identical to the original, with a new width and image path:

#thome a  {
width: 46px;
background: url(guides_lg.gif) top left no-repeat;

fig. 3
Figure 1.3

Figure 1.3 shows the larger tabs as they appear on Fast Company, where you’ll notice that the horizontal spacing is tighter while the vertical size remains the same as the original. But, by adding the ability to increase the size of hypertext as well as the tab images we’ve helped out low vision users, while still working with our certain design constraints. Thanks to Doug for this solution.


Tested and working in Windows: Mozilla, Netscape7, IE5.0+; Mac: Mozilla, Camino, IE5, Safari.

Specifically for Fast Company, I choose to position: absolute the #nav in order to make things line up perfectly, letting the background color of the header area show through underneath. This works fine and dandy — except in Opera7/Win where specifying a width is necessary for absolutely positioned elements (ugh). That’s OK though, we’ll just add the total width of the images (added up) to the #nav:

#nav {
margin: 0;
padding: 0;
height: 20px;
list-style: none;
display: inline;
overflow: hidden;
width: 201px;

Now we can sleep at night, and Opera fans rejoice.

Special thanks to Paul Maiorana for letting me bounce ideas off of him (repeatedly) at the office.


  1. Ethan says:

    Very nicely done. A seamless integration of a few different CSS techniques…and it scales down to 800×600 beautifully, too. Looks great.

  2. Anonymous says:

    This is great! This is something that has been in the tip of my (and probably many others) brain since these techniques were introduced. Thanks for putting together such a comprehensive study, this is extremely helpful.

  3. Chris says:

    It’s not working in my Mozilla Firebird. I’m using 0.7+. All I see on the axamlpe page is a blue box.

  4. Jeroen says:

    Somehow Mozilla does not load the background images of the example page until the moment you move your cursor over the tabs to change their status.
    The FC site does not show this problem, so I suspect that the code of the example page is a little bit too much simplified…

  5. As above, this is exactly the sort of thing that I’ve been hoping for, but it doesn’t seem to address everything… and I don’t want to minimize that at all. But for users with reduced vision, using images instead of text means that they can’t scale the size of the links up and down. These people, who fit somewhere between those with perfect vision and those who would need the use of screen magnifiers, will have a heck of a time reading those links if the font is too small. What’s the solution?

  6. Good, thorough write-up Dan. The tabs look good and function well. It’s a tough challenge when the site’s producers/managers want to add so many items to the navigation. What do you do when the row of tabs gets so long that it begins to wrap at a standard minimum 800×600 resolution, breaking the design? It’s a tricky one. As designers/developers, we often don’t have the authority or convincing power to ask management to strip down the amount of navigation to a simpler set, just because they “don’t fit”. It’s a business and editorial constraint.
    That said, the low-vision user is a concern. Maybe you just haven’t had time to cover it yet and are already planning some changes. It would be more work, and require a little more maintenance whenever you changed images, but you already have two alternate style sheets for Medium and Large text sizes. You could create larger-text images, and use them in the two alternate style sheets. The design may have to change a little for the alternate versions to accommodate larger tabs, as you’ll eventually run out of horizontal space. But at least the tabs would be somewhat “scalable”. Keep up the good work.

  7. Dan says:

    Chris and Jeroen – Seemed to work fine in Firebird .6 (WinXP). I’ll take another look.
    Jamaleddin – Tough call. Using images for navigation surely has it’s drawbacks, but when it’s necessary (as often times commercial sites call for necessary evils) then we can at least make the best of it.
    Doug – Hmm, great idea on creating larger tab images for the alternate styles. It is… uh… exactly what I was going to do :)
    Like you said, it’ll be tricky to fit larger ones into the design, but certainly worth a shot. Thanks.

  8. eric says:

    Breaks in my Firebird .7+ running on XP Pro as well.
    Looks nice in IE6 and Opera 7, though.

  9. Ethan says:

    On the FB tip, the issue is that recent Mozilla builds don’t play nicely with the LIR; it’s currently filed as Bugzilla bug #220266.

  10. Dan says:

    Ethan – thanks for clearing that up. I feel better now.

  11. Ethan says:

    Dan — anytime. Just wish they’d fix the darn bug so my site didn’t look like a decapitated sunflower, but c’est la vie. ;)

  12. Your timing is incredible, I just spent most of the weekend figuring this out. My problem was the large number of rules (nav+subnav > 15 items) got a little confusing. Your code does simpilfy it a bit though, maybe I’ll revist it this weekend.

  13. I was also trying to get the “selected” functionality from the body id which allows the same nav code on every page. (like doug!)

  14. Blake says:

    I recently got done coding a site using the same method for the nav. Works great, just like you outlined. However I am having probems with it in IE. the tabs flicker upon each :hover. Can anyone have look around, it seems it may be a server issue. Here is the url of what has been done.
    Check it out in IE 6.0 to see what I am talking about.
    Thanks for the write up on the method!

  15. Oooh – larger images from larger sheets – nice save, Doug! Also, Blake, you need to change your settings for your IE Cache: Tools – Options – Temporary Internet Files – Settings – then change "every time" to &quotAutomatically". Hope that helps.

  16. Darrel says:

    This is a great technique and agree that it can be quite useful to fix the necessary evils of client demands.
    That sad, the final solution is quite unreadable. I have good eysight and can barely make out the blurry miniscule type used for the images. So, I do see that while this makes handy CSS/XHTML code, I’m not sure if it really benefits the end user at all.
    I do like the one-image for all rollover states, though. Clever!

  17. Blake says:

    It is set to automatically, that is why i think it is a server issue. It is on apache.

  18. Hmmm – I dunno – if it were the server, wouldn’t it be happening with other browsers? Back on topic, is there a way to add the various techniques outlined in Douglas Livingstone‘s article at SitePoint to get text when images are turned off? Just a thought…

  19. Philippe says:

    Nice technique, ‘xcept the images are pretty small (with rather low colour contrast). That said, you could add a small improvement, to the benefit of keyboard users :
    #nav a:focus {background-position: 0 -20px;}
    Combine that with the #nav a:hover.

  20. Michael says:

    Very clever technique! Thanks for taking the time to describe in such detail.
    One small correction: in your working example with sourcecode you left out the following from your example-specific css:
    #container {
    position: relative;
    width: 500px;
    height: 30px;
    padding: 0;
    margin: 3px 0 20px 0;
    background: #7FA0B1;

  21. Dan says:

    Update: Thanks to Doug’s suggestion, I’ve updated the article to include an image scaling solution, using the indespensible stylesheet switcher. This should improve readability for those with low vision.

  22. Web says:

    I am running IE6 and when I mouse over a link on the navigation (on fast company), it disappears for just a brief milli-second then reappears correctly. I think this is an IE setting I saw somewhere. After a fair amount of link searching I cant find it again.

  23. Mike Rundle says:

    Hey Dan, they look awesome!
    If the Mozilla bug bothers you (lookout for shameless plug), you could always use the text-indent thing that I use: Accessible Image Replacement.
    The overflow property kills IE5 for the Mac, so you probably could just do away with it and increase the text-indent to like -1000em…. or hack around it.
    Just a suggestion ;)

  24. Al says:

    I know typography is the obvious answer, but is there another reason why you didn’t ditch images altogether and use Eric’s “Rounding Tab Corners” technique instead? That would help with scalability more than alternate image styles I think. And I still don’t think it’s enough of a convention for people to look somewhere on the page to resize their text – most of the novice users at our work either resize from the browser menus or don’t know about it at all. Sad but true.
    Hope that didn’t sound like a snark! Just curious.

  25. Dan says:

    Al – While Eric’s rounded tab corners do rock the house, using text was not an option in this particular case. At a tiny font-size: 10px, there was no room horizontally to add any more links (at 800×600). Using images was the only way we could fit what we needed.
    But, I’m hoping people can look beyond the Fast Company example and see the technique for what it’s worth — when you want to (or must) use images for navigation, it’s an option with advantages over using images inline in the markup.
    And depending on the room, you could certainly make the text as large as you wanted to for the tab images.
    Michael – thanks for letting me know on the source omission. I’ll add that bit back in.

  26. Russ Baldwin says:

    First up Dan very nice design and use of CSS. You said…”I wanted to continue to use a simple unordered list for the navigation in the markup…They’re compact, lightweight and accessible to text browsers, screenreaders, PDAs, phones, etc.” and I’m with you all the way.
    The problem, is not with screen width here, but that some PDA’s (Pocket PC Windows Mobile 2003 and some new Palms I believe) have browsers with CSS support which you cannot hide with @import. Worse still the CSS support (in Pocket PC 2003 at least) can be ‘incomplete’ to say the least and would seem to support some postioning elements. I have pda screen shots of the fastcompany site and how it breaks, if you would like them. Corporates are increasingly using thes new Pocket PC’s – now a better seller is Australia than Palm. Dell has a huge chunk of this market and is forcing prices down. I’ll try and find time to download the Palm emulator and SmartPhone emulator, to see what happens in those pda’s.
    Other than that I think it is a great display of what you can do with CSS and lists.
    Keep up the good work,

  27. Mike Rundle says:

    I was just thinking about it, and there might be a way to change images based on the browser’s text larger/text smaller menu options.
    By using the background-position property with em’s instead of pixels (and lots of experimenting!), the image’s position could shift with the resizing of text.
    Check out this code example for an extremely small example that might get your creative juices flowing ;)

  28. Well it’s a nice trick – some people and i were discussing this trick a couple weeks ago, and we found that the only real problem with it is this:
    in ie/win, if you have your cache settings set to check for updates ‘every visit to the page’ you get a little bit of a flicker (as a couple people have pointed out in the above comments)
    so for me, the flicker is enough to keep me away from it, but i think for most common users it should work out great.

  29. Mike Rundle says:

    My code’s been tested in Safari, Camino and Mozilla for the Mac, as well as Mozilla for Linux.
    I did tweak it a bit after I posted, so it should work now ;)

  30. Dan,
    In a reply to Al who asked about using Eric Meyer’s rounded corner tab method, you replied, “While Eric’s rounded tab corners do rock the house, using text was not an option in this particular case. At a tiny font-size: 10px, there was no room horizontally to add any more links (at 800×600). Using images was the only way we could fit what we needed.”
    Can you explain that a bit more for me? How did creating images allow you to fit more entries on the nav bar than text?

  31. Dan says:

    Joachim – The Mozilla issue has already been addressed.
    Paul – we’re designing with a minimum browser width of 800×600. We need things to fit at this resolution, mainly for advertising purposes. Previously, we were using font sized at 10px for the navigation (yes, with pixels which I realize is bad bad), and we were maxed out. Adding another item (and we needed to add three) would’ve broken the design, causing a few items to wrap to the next line. Using images, we can of course use a skinnier font and cram more items to fit in that minimum width.
    No, it’s not ideal, but it’s something that needed to be done. Hope that clears it up a bit.

  32. Nick says:

    Russ, those PDA browsers you mention that do support @import also support CSS media types. I know for a fact that on the new PocketIE installed on all new Pocket PC devices, any styles with a media type of handheld will override any other style. So if you @import a style sheet with a media type of all or screen you can override those styles on these new PDA browsers with a style sheet that has a media type of handheld. Of course, if the selectors are not in the handheld style sheet, the PDA browser will use the associated style from the screen/all style sheet but that should be expected.
    I believe the new Palms ship with NetFront 3.0 which has even better support for standards than the new PIE.

  33. Adam says:

    Great technique (but you already know that… see above).
    I have one thought around readability. The small text, everyone is likely to agree, is difficult to read. However, most people don’t need to read everything to know what they are doing. They typically need to know where they are and what they are looking at. Its why we have difference colors for “current” and hover states.
    But why do we just vary the colors? Why not have a larger tab for the current and hover states? As long as there is the horizontal room for it, this should work. Sort of like the OS X dock (only less smooth)
    Mind you, some people (mostly designers I think) get annoyed at the idea of stuff moving like that.

  34. Shawn says:

    New Palms (Tungsten C and up Palm OS 5.2.1+) are shipping with Webbrowser 2.0 which DOES NOT SUPPORT MEDIA TYPES.
    The CSS support may be good for a handheld, but since I can’t tell it to use a handheld media type it is all but useless for trying to develop content/code that works well in all devices.
    Any site that is trying to do a centered fixed width layout simply does not work in the palm browser.
    Palm’s documentation encourages developers to do browser sniffing and send users a Palm friendly page.. so at this time, I don’t think they really care about media types. That said, they do provide a comprehensive listing of what CSS1 & 2 attributes they do support (Download their Webbrowser 2.0 SDK – there’s a pdf with detailing all of the JavaScript, HTML, and CSS support)
    I have written Palm on issue but to date have not heard back (months), at this point I am not holding out hope.

  35. Paul Y. says:

    I was actually at when it changed, I was kinda confused for a second, “hey when did that blue part get there” :)

  36. Niket says:

    While the idea behind this design is cool, I would term this an overkill. Thanks for the tutorial, though I don’t think I will ever use it.

  37. Dan says:

    Niket – Not sure I see how it’s overkill. Since we were confined to using images — overkill would’ve been coding each image inline on the page, then using Javascript to handle the rollovers and pre-loading the second set of images, saturating the page with excess code that only certain browsers will be able to display at all ;-)

  38. i wonder how this would work in a sample gui i am developing based on the typepad layout? (its going to be a multipart form in a single xhtml document.)

  39. Web says:

    Yeah, I changed my cache to automatic and sure as a Red Sox error in the 9th, it worked.

  40. Niket says:

    Well, javascripts are well past overkill. Ever since hover pseudoclass got adequate cross-browser support, I threw javascript out of the window :-)
    There is something about image replacement that I am not too comfortable with. To me FIR is OK, inspite of the redundant <span>, because you can SEE whats happening without stretching your brains too far. But the other IRs that use paddings and margins and overflow:hidden and so forth are more than what I can digest. It seems we are going from tag soup to a css soup.
    I want my life to be simple. If tomorrow I am asked to take over the design of, I should be able to understand what you have done without requiring to spend 5 hours understanding why you used height: 0 etc for your navigation links.
    My outlook differs from most other replies here, probably because web design is not my profession. As I said, the tutorial was interesting and I did a small “project” of my own to make it work; but still its an overkill for me.

  41. Roshambo says:

    It totally breaks for me. In Firebird (0.7+) it just plain stops. Nothing happens at all. In IE6 their is a huge delay between swaps, and often the swap never even finshes–the first image swaps out and I’m left with an empty space. Even Pixy’s Original Method is dying on me. I admit my machine is running rather slowly today, but it’s still a P4 1.3Ghz machine with a good video card, and a machine that young shouldn’t be experiencing delays like this. Other sites still implementing the older JavaScript-style rollovers are working well in both browsers.
    Unfortunately as it is, the example shown here is not yet a viable solution.

  42. Dan says:

    Roshambo – The Firebird issues have already been talked about earlier. Recent builds of Mozilla appear to be slightly buggy in this respect.
    As for IE6, I’m not seeing any lag whatsoever, although I sure would be interested to hear if others have. This is obviously the most popular browser, so it was checked rather rigorously on it.

  43. Rahul says:

    I don’t really see the benefits of using images for this – maybe to reproduce the rounded corners, but with not-really-graphical text, why not just put the actual list element content there? It’d be easier to style for accessibility and use up less bandwidth (albeit 100b or so). I guess I just don’t see the point of having images in your list nav menu for the sake of having images. You might as well take it to the next step and either make the images more visually interesting or combine them with the element content.

  44. Dan says:

    Rahul – I’m beginning to sound like a broken record. We could not use hypertext for this particular situation (as I’ve explained in the tutorial). I certainly would never use an image for the sake of using an image — and I hope that’s not inferred from the article.

  45. Dan R. says:

    Great job Dan, I’ve been dealing with an almost identical issue with one of our current projects (same problem, came up with the same solution).
    I love using one source image per-rollover, though on SuperfluousBanter I went even further for the rollovers on my three Style Switcher buttons — one source image fuels all three rollovers, modifying left and top background position to move the image. It saves 2 http connections, which doesn’t hurt the site-load time.
    I suppose by using one wide source image, you could reduce the http connections for the Fast Company navbar from 10 to 1, and possibly save a few bytes in the process…

  46. Sebhelyesfarku says:

    This image replacement method is useless, because doesn’t work with images turned off (low bandwidth, etc.). If you go to the fastcompany site with images turned off there’s NOTHING, no tabs, no text, no navigation. Useless.

  47. Dan says:

    Dan R. – Ah, interesting — so there’s still only one set of images that includes noral and large text sizes. I like it.
    Sebhelyesfarku – Useless? I disagree. Would images have shown up with we had coded them inline on the page and then used javascript to handle the rollovers? Nope.
    This isn’t a 100% perfect solution, but when dealing with commercial sites — there rarely ever is.

  48. Niket says:

    Dan, regarding your reply to Sebhelyesfarku:
    If you coded your page with inline images, and viewed it with images turned off, you will see the alt text instead. If you view the fast company page with images turned off, you will see no navigation bar at all.
    My take on this is that IRs aren’t way better than using inline images. If images is how you want to represent information, you should use inline images. In the fast company example, the way I see it, you do not prefer to use images; you are using them because there isn’t a globally availabe narrow font.

  49. Dan says:

    Niket – you said: “In the fast company example, the way I see it, you do not prefer to use images; you are using them because there isn’t a globally availabe narrow font.”
    You are absolutely right. I would certainly prefer to use hypertext, and for non-styled viewers, screenreaders, and various other devices — that’s exactly what they’ll get.
    Interesting point on the lack of alt text. I do think image replacement has its place though — especially for things like navigation and headings — areas where redesigning may occur. Keeping these interface images within the CSS has obvious benefits.
    If I were placing a photo of a monkey within an article about monkeys — then the image would certainly belong there more than just replacing the text “monkey”.

  50. Rahul says:

    Dan – Sorry about that, apparently I did misinterpret the tutorial, wondering why 10px hypertext type wasn’t just chosen – but I suppose that borders on illegibility… not to mention resizing would likely screw up the design.
    Question, though – what if you wanted to float the navigation on the right (perhaps for an rtl-stylesheet) without reversing the display order or the physical html order?

  51. Mike W says:

    Sorry for being a bit late with this contribution but I have to work on week days.
    I’m sorry but I do not think you can claim No Javascript or It’s Accessible for this menu for the following reason:-
    One has to use Javascript to make the menu accessible (stylesheet switcher) to those with poor sight but this use goes against the Web Content Accessibility Guidelines 1.0. I think the below covers it.
    6.3 Ensure that pages are usable when scripts, applets, or other programmatic objects are turned off or not supported. If this is not possible, provide equivalent information on an alternative accessible page. [Priority 1]
    Besides, accessibility is the whole point of not using images to convey text.
    Incidently, it seems that some visual browsers, if not all, load background images last. I have to wait over a minute in IE Mac/OS9* before the menu appears. I thought that the design had broken when I first looked.
    * I do audio editing and, like over 80% of users, have a dial-up connection.
    On the subject of lists for menus, has anyone read paragraph 17.2 of the CSS2 specification W3C REC-CSS2-19980512 (PDF version) which states:
    ‘User agents may ignore [p. 42] these ‘display’ property values for HTML documents,
    since authors should not alter an element’s expected behavior.’
    (X)HTML does not address the inline, punctuation delimited list and, perhaps, it should. An <il> element, maybe.
    What is all this about 800×600 displays being the standard minimum. All iMac owners until recently and most non power-users with PCs have 15 inch displays and when you have added the favourites bar, the tab bar, the mini bar and the Mars bar, I would say that 800×600 is the standard MAXIMUM and that is before you even think about PDAs etc.
    The internet is a different medium, nearly unique in how much control the recipient has over how to use it and has a different dynamic to the others. Maybe it’s time to move on from the static page/print model.
    Phew, that was a long rant. Sorry.

  52. Dan says:

    Rahul – Great question, on rendering the menu aligned to the right. I’ve tried getting this work before, but didn’t see it through. Would be a good trick to figure out though.
    Mike W – you got me on the style switcher (javascript) :-) This bit was added on to at least handle the legibility issues with the small type on the FC images. Depending on the project though, you could of course make the images as large as you wished.
    The Accessibility claim comes mainly from the use of “accessible image replacement” (in this case Stuart Langridge’s method), rather than the Fahrner method which causes mixed results in screenreaders (due to the use of display: none;). The overflow: hidden; trick is meant to get around that, so that screenreaders will indeed read the text of the li.
    So, perhaps I shouldn’t have titled the article with the term “accessibility”, but hopefully that helps clear up why the term was used in the first place.
    Re: 800×600 being the mimimum resolution, this is often the benchmark due to various standard advertising sizes that are required on the page. For instance, the nasty “leaderboard” type ad that often sits at the top of the page is 728 pixels wide. Add some padding, and the interface elements you spoke of, and you have yourself a minimum width to deal with.

  53. Dan R. says:

    Actually, in my “from 10 images to 1″ calculation, I forgot to account for the large version of the menu images. If you made one image which included both standard and large images, you would go from 20 http connections to only 1.
    Since the actual amount of data transferred would be the same (or less), you would only speed up the display of the site, especially to modem users. It even means 1 cached image for the browser to load at a later date, rather than 20…

  54. Rahul says:

    Here’s another question – considering you had to resort to using this menu due to limitations imposed by the width of the design, did the client ever get involved in the choice to move over to this technique, or was it an internal decision? Just wondering, since I’ve had enough clients that make a big deal over things like having to have the menu not wrap even if you add 200 items to it (…). Not that I can foresee a client complaining about this technique, unless they were part of the accessibility experts group that have been commenting here..

  55. Mike W says:

    Thank you for your reply to my comments.
    Just 2 things:
    My reference to the display property was aimed more at the changing of the list from ‘list-item’ to ‘inline’.
    In IE5Mac/OS9 if you have the favourites bar expanded, and I’m sure many do, it takes up half the viewport and I cannot find a way of narrowing it except by dismissing it altoghether (Actually I don’t use IE as my browser of choice, merely as one benchmark for my designs.)
    OH. If you want (need) an infinitely long menu suggest to your clients that it runs down the left hand side of the screen. There it also becomes the last thing that disappears as the user shrinks the window (does he need a reason?) and you don’t have to change the expected display of the list element.
    I’ve just thought of something else but I shall stop

  56. Rahul says:

    In terms of other methods, perhaps it would have been possible to suggest that the information architecture be re-analysed in order to allow the menu itself to be shortened, or a submenu to be built? On the new design for my own website, I made the design so that the top horizontal menu only contains four items and they’re each large and clear enough to be read without having to adjust stylesheets or whatnot. It doesn’t exactly benefit the clickthrough, but at least it removes a “bug” from your design.
    Of course, we don’t know what the client’s demands were in this case, so it’s hard to say what the best alternative would be…

  57. if you place background images on anchor tags, and ie is set to “always check if the page was updated” the image flickers like hell.
    to avoid that, put the background images to the list items and use lir on the anchor tags. you can make an ie version and a good version (with > selectors) too.
    we had this problem with plone version 2 on eduplone (which is not completly finnished yet).
    regards, Michael

  58. Brad Smith says:

    I’m experiencing several problems with it that I also reproduced on a design I’m working on…
    In Camino the tabs don’t render at all.
    In OmniWeb/Safari, the rollover states don’t reset if you leave the navbar. Is there anyway around this?

  59. Michaël Guitton says:

    Speaking of accessibility, why not use a client-side image map? Granted you’re almost out of luck for rollover FX but at least, you can benefit from alt text for specified areas (for text-only browsers or people who have disabled image display). You also get access keys and tabindex. And you would only download one image for the whole menu instead of one per tab… Dunno if it’s possible but one could set a transparent image map, attach a background thru CSS and then use ‘background moving’ hover trick to achieve a rollover FX.

  60. Benry says:

    Thanks for this. One problem I’ve come across in this implementation is that if you use IE6 PC Accessibility options (TOOLS > INTERNET OPTIONS > ACCESSIBILITY) and check the box that says “Ignore Colors Specified on Web Pages” you see nothing.
    However, performing the same on Pixy’s site, provides a list of links.
    Any ideas?

  61. Nick says:

    Getting back to the IE-flickering problem: I get it even though I have the Cache set to “Automatically”. Any ideas?

  62. Daniel says:

    Hello Dan, your tutorial is great. Many thanks for that! I used it constructing the website mentioned above. But you should add a “hover”-behaviour to your “selected” items. So users won’t get the “hover” graphic if they go mouseover a previously “selected” button – it will stay fixed:

    #nav a.selected, #nav a:hover.selected
    background-position: 0 -40px;

    I didn’t see your code causing problems on my Macintosh IEx, but the PC IEx hovers the selected buttons – that’s why I needed to improve the code. Perhaps it’s helpful for others…
    Your page looks fantastic!
    Many greetings from Berlin, Germany
    Daniel Ojala

  63. Micha says:

    Please read Danny Goodman’s Super-Efficient Image Rollovers (featuring a 3-state rollover client-side image map; CSS + JavaScript combo.) It works will all W3C DOM-compatible browsers and web crawlers!

  64. Micha says:

    Please read Danny Goodman’s Super-Efficient Image Rollovers (featuring a 3-state rollover client-side image map; CSS + JavaScript combo.) It works will all W3C DOM-compatible browsers and web crawlers!

  65. Micha says:

    Please read Danny Goodman’s Super-Efficient Image Rollovers (featuring a 3-state rollover client-side image map; CSS + JavaScript combo.) It works will all W3C DOM-compatible browsers and web crawlers!

  66. Micha says:

    Please read Danny Goodman’s Super-Efficient Image Rollovers (featuring a 3-state rollover client-side image map; CSS + JavaScript combo.) It works will all W3C DOM-compatible browsers and web crawlers!

  67. Micha says:

    Please read Danny Goodman’s Super-Efficient Image Rollovers (featuring a 3-state rollover client-side image map; CSS + JavaScript combo.) It works will all W3C DOM-compatible browsers and web crawlers!

  68. John39 says:

    I have a bit of a problem here.
    I love this method, but if I remove position: absolute; and make it anything else, mac/ie shows the text links, too. (The height value seems not to matter anymore.) I can’t seem to get around it.
    Or, rather, I don’t know what the best way around it is. I don’t have access to a mac on a regular basis, which means getting around its peculiarities is a bit difficult for me. Any ideas?

  69. Richard says:

    I regards to the posting by “Web” which noted: I am running IE6 and when I mouse over a link on the navigation (on fast company), it disappears for just a brief milli-second then reappears correctly. I think this is an IE setting I saw somewhere. After a fair amount of link searching I cant find it again.
    This is a browser interface issue with WIN-IE knon as “flicker”. It occurs when you apply an image background to an link tag element. WIN-IE will reload the image source each time you pass over the link element when altering its background, in this case moving the placement of the image. In general this is BAD because WIN-IE in the majority browser and this places an increased load on the providing server and consumes wasteful bandwidth.
    I too love this solution. But I discovered this WIN-IE interface “flicker” issue when building a similar CSS technique for a web site for a Web Analytics Software Company. Ironically, it was they who discovered the increase in additonal server hits and the flaw in the CSS design technique for “swapping” background images on an link element. Thier web analytics software reported the hits. It is just to bad that WIN-IE only supports the :hover psuedo class for link elements instead of most any element like the standard.
    The pros/cons of this technique. PRO: Looks Awsome CON: Hope the Server Admin does not notice the additional server hits. Doh!

  70. T. Error says:

    Pretty good Tutorial. Very detailed and easy to follow.

  71. Bryan says:

    This is just nitpicking, but are you aware that your example does not have ending tags ?
    doesn’t XHTML require that?

  72. Ed says:

    I’ve read through all these comments and while I think this technique looks great, I’m worried about some of the issues mentioned above.
    My target audience isn’t Pocket PC’s and PDA’s. It’s IE and Netscape. The flicker issue poses a problem, as IE is my largest audience of users.
    While my main goal is to redesign my site to encompass CSS and XHTML, I’m starting to think that my old Javascript image-based navigation is the way to go.

  73. John says:

    How come you didn’t do something about the Windows IE “flickering” bug for Fast Companies top nav? doesn’t work well in my version 6.0 browser. Everything else looks great by the way!

  74. Benjamin says:

    This article was a huge help when I build my small wed design firms site. However, when I recently upgraded to Mozilla Firefox 0.8, they no longer work. The ones on Fast Company have “quit” working as well.
    This is by no means intended to be a complaint of you’re great article, just an observation. Hopefully, we’ll still be able to use this “trick” in the future.
    Thanks for your great work and writing, Dan,

  75. Vladdy says:

    One problem with semantics:
    Background image represents a link, list is just a way of organizing links. Therefore you should give id to anchors not list items.

  76. José Jeria says:

    It seems like this doesnt work with Firefox 0.8 on MacOS X as commented above. This works though on nightly builds, so most probably it will work in the next release as expected.

  77. Shareholder says:

    Sorry, but on my Mac 5.1.2 is doesn’t show last Archive-item.
    And on my Mac Mozilla 1.6 it doesn’t hilite anything. I am on OS-X 10.1.5

  78. Shareholder says:

    Mac 5.1.2.. I meant IE 5.1.2, of course.

  79. Promark says:

    It’s not only Firefox on Mac, but Win as well. Links show, but nothing happens on rollover :(

  80. cstaylor says:

    It seems like a bug in Mozilla 1.6′s hover pseudoclass

  81. cstaylor says:

    Yes, it is a bug. I checked with Bugzilla at, and it’s been filed.

  82. mini-d says:

    I had the same problem on Firefox 0.8.

  83. global says:

    Try in your nav ul li
    #nav ul li {
    display: inline;
    float:left; /*fix */
    margin: 0;
    padding: 0;
    Fix the hover bug for me under firefox in order to display the background position

  84. Todd Dominey says:

    Global’s css tweak DOES fix the issue with Firebird / Mozilla, but I found that it breaks the nav in Internet Explorer 5.0 for OS 9 and under. Interestingly, it works fine in IE 5.1 for OS 9, but not 5.0. Odd.

  85. Todd Dominey says:

    As a followup to my above post, here is a solution: wrap the “float:left” attribute like this:
    /* hide from IE mac \*/
    /* end hiding from IE5 mac */
    With that, the nav works perfectly in all flavors of IE I could find, Firebird, Safari, etc.

  86. Andy Price says:

    Hey Dan,
    Great article! I’ve been playing around with this technique myself and have had some good success. Also, i added the styleswitcher script and it works very well locally, but when I upload and try to switch themes in IE6 it throws an error about an object being expected.
    Any thoughts? The folder structure is exactly the same on the server as is locally to me..odd indeed.

  87. Andy Price says:

    Well, it turns out it just didn’t like my relative path to the .js file. Switched to absolute and all is well.
    Thanks again for the great read!

  88. Funkatron says:

    For some reason, the hover states don’t work in FireFox .8 for both the example and the site. Surprisingly, it works in IE6. Does this have to do with the bug mentioned earlier?

  89. Dominik Hahn says:

    In Moz 0.8 it doesn’t work but it did in mozilla 0.7 :)

  90. Rob says:

    Hi all….
    Interesting technique…
    I’ve actually gone one step further here, and I can say my entire nav is using just 1 image…. that right, all nav items, and all states are in one image.
    On top of that, it works with images turned off. It also degrades very well in other browsers including text based browsers (lynx for example) and browsers that dont support css.
    I am hoping it’s ok in non-windows browsers (I’ve tested ie 6, netscape, mozilla, firefox(yes, fixed the bug) and also opera.
    The bug in firefox has gone (don’t ask)
    I would be interested if people could give me some feedback on any browser issues.

  91. Romain says:

    Rob, your exemple works perfectly on Camino 0.8b so far.
    Let’s get back to the topic now…
    I see there are limitations with the suggestion that Dan generously offered to us. Mine is different from what I read above. Well, some readers did express the same concern but it seems that nobody could help them. Let’s just rephrase our concern : each working example I see is using :
    #nav {
    position: absolute;

    So it works only if the navigation bar is absolutely positionned. So far all my attempts to make it relative to it’s parent div have failed.
    When relatively positionned, the navigation bar isn’t properly refreshed. The mouse position doesn’t trigger the hover effect, or with difficulties (latest versions of Camino, Firefox, IE and Safari on OS X) . If anyone finds a solution (because like others I simply like the navigation bar to be centered), we’d be happy to read about it.

  92. Mike says:

    Hi firstly thanks, for the great article, ok not sure if this is a silly comment, thought I should mention it though. I was testing the company site out with Opera 5.5 on Win2000 pro and this technique, just doesn’t seem to work well – is it because Opera 5.5 is so old?

  93. Gence says:

    Doesn’t work with Mozilla 1.6
    Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.6) Gecko/20040113
    Is there ANY non-javascript solution that would work with browsers up to 3 years old?

  94. Thomas says:

    Very thorough and useful tutorial. Thanks for sharing this!

  95. Javier says:

    if you put border:0px solid #fff; to your hover css, in firebird/firefox it works fine…

  96. Tony says:

    Re: comment 94.
    This can cause a flicker affect on neighbouring divs when divs float left in Firefox 0.9 and Netscape 6.2.

  97. Vanish says:

    Thank you, thank you, thank you! I’ve been struggling with removing all formatting code and converting sites to pure XHTML and CSS. This was the last thing I had to figure out, and you solved it for me!

  98. :-)
    Really, thanks!!! Nice work… Keep helping…