Dave Shea recently published an article on A List Apart (ALA), CSS Sprites2 – It's JavaScript Time', about how to use jQuery to create the effect of animated rollovers on navigation items. The technique he outlines makes use of the same image replacement method as outlined in ALA's original Sprites article.
The problem with this method however is that it uses a large negative text-indent
to remove the default text from screen, and with images turned off in the browser, you don't see anything. This has accessibility implications not only from the perspective of those with disabilities, but also for those who deliberately turn images off, i.e. people on slower connections or those using handheld devices who are trying to limit the amount of information downloaded to their phone.
When I do use image replacement, I prefer a method which leaves the text on screen when images are turned off – the Gilder Levin Ryznar Jacoubsen IR method, which I've written about before. Having been using jQuery quite a bit myself lately, I thought I'd see if I could come up with a similar implementation which would let me use the image replacement method I prefer.
Here's my working example.
The mark-up is essentially the same as that Dave has used:
except that I'm using IDs on my list items and rather than having a class on the ul
to identify the current page, I've got an ID on the body
. The CSS looks like this:
The only additional rules added to get the animated effect to work are:
And the javascript:
Essentially, what's happening is that javascript is being used to append an empty to each anchor which is set to display: none
by the CSS on page load, and when the mouse hovers over it, the is animated to fade in.
Except that it's not quite that simple. Because there's already an empty in each anchor which handles the rollover effect if javascript isn't available, and because the change of the background-image
on hover happens immediately, you don't really notice the fading in of the hover state of the image because it's fading in over the top of an image of itself.
So what I needed to do was to remove the background-image
from the when each anchor was hovered over – #nav .over em { background-image: none }
. But this would then leave the text of each link visible, so I also needed to use text-indent
to remove it from view – #nav .over { text-indent: -999em }
. Using a negative text-indent
was one of the reasons I shied away from the technique used in the ALA article, but at least in this example, the text is still visible in its normal state if images are turned off and only disappears when hovered over.
The javascript for this example is a bit lighter than the ALA example and it ticks a couple more accessibility boxes in that the animated effect will work for both mouse and keyboard-only users with both :hover
and :focus
events, and the text of the links is still visible with images turned off, but as mentioned above, it does still need to use text-indent: -999em
which I would've preferred not to have used. So if anyone has any ideas about how to remove the need for text-indent
, I'd like to hear them.
Update
I noticed recently that Firefox has a problem when clicking the links in that it was layering a second empty span over the top of the first one applied by the part of the script that produces the effect for when the link receives focus only rather than hover. The second empty span was preventing the browser from redirecting to the anchor destination. So I've modified the script to check whether the class of over
has already been applied when the link receives focus and only apply the class and the extra span if it hasn't been.