Tuesday, September 12, 2006

IE CSS Rollovers - Revisited

Haven't had much to say lately, as I have been busy trying to wrap a project. However, I felt like this was worth taking some time to share it.

Basically, the IE Rollover Cache Bug came back to bite me today. Now, there are many documented solutions to avoiding that annoying flicker in IE when you change the background image of a hyperlink. My personal favorite is this one. But what about the browser activity indicators that are stopped and reset when you mouse out of the button? I see far less discussion of that issue, and know of no solution expect for the one I'm about to document.

Let me describe this in a little more detail. If you click a hyperlink that has a background image, all of Internet Explorer's browser activity indicators will be stopped and reset when you move your mouse off of that hyperlink. By 'browser activity indicators' I mean the 'spinner' (wavy window animation) in the upper right corner of the browser, as well as the status bar at the bottom of the browser (in WinXP, this is green & segmented). This gives the impression that the page load is complete when in fact it is not - the requested page will be displayed eventually. This happens regardless of whether you are changing the background-image property. If you change ANYTHING about that hyperlink (border-colors, sizes, text-decoration) the activity indicators will be interrupted. I can readily confirm this on IE 6, and I'm pretty sure it happens in IE 5.5. IE 5 seems to be immune. I hope to god it's fixed in IE 7.

Typically, this is not a problem because page loads happen pretty quickly these days. But if your link is submitting a form and the server takes some time responding, this can get to be quite a problem. Thinking the form submission has quietly failed, the user will click the button repeatedly, badgering your server with extra requests. Bad for the user, bad for you.

Onward to the solution. I was almost ready to give up and ban image rollovers entirely, when it occured to me that there was one last trick I hadn't tried yet. All you have to do is display the image using Microsoft's proprietary DirectX filters instead of the normal browser pipeline. Here's what you do:

/* Set up your rollover as normal */
a.MyButton{

background:url('Images/MyButton.gif');
}

a.MyButton:hover{
background:url('Images/MyButtonOver.gif');
}

/* Now hack for IE (using star hack for brevity here)*/

* html a.MyButton{
background:none;

filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='Images/MyButton.gif',
sizingMethod='image');
position:relative;
cursor:hand;
}

* html a.MyButton:hover{
background:none;
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='Images/MyButtonOver.gif', sizingMethod='image');
}


That's basically it. Since the problem only occurs in IE, I'm fine with using a Microsoft proprietary solution. Now, AlphaImageLoader comes with its own set of caveats and gotchas, not the least of which is that you can't position the image at all. Sometimes I need to. As a workaround for that, I put an empty div in my hyperlink to which I apply the image instead, and then position the div with absolute positioning. Another point to be aware of is that sometimes hyperlinks will not function if they have an image applied in this way. However, position:relative should cure that.

I hope this helps some poor frustrated soul. As always, please post any questions or comments, and I'll do my best to find the answers.

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.