All in the <head> – Ponderings and code by Drew McLellan –

When Bugs Collide: Fixing Text Dimming in Firefox 2

Example of the visual affect of Firefox 2 switching anti-aliasing methods When working on front end development projects, we’re finding that a great many more sites are taking advantage of small JavaScript animation effects to make interactions feel more polished. One thing you may notice if you use Firefox 2, particularly on a Mac, is that as you animate the opacity of an object the text on the whole of the page can appear to dim slightly. This, in fact, happens with any change of opacity on the page.

The effect is particularly noticeable when the page’s colour scheme uses light text on a dark background. What’s happening is that Firefox is switching from using the operating system’s text anti-aliasing to using its own internal system. As you can imagine, when you switch from one system of anti-aliasing to a completely different system this can have a noticeable impact on the appearance of any type.

This clearly isn’t a new problem, and the anti-aliasing switch is no longer apparent in Firefox 3. A common way of addressing the issue is to force Firefox to use its own anti-aliasing from the outset by setting the opacity on the entire page to something very close to the maximum value of 1. Typically 0.9999 or similar. This has no visible impact other than to kick Firefox into a text rendering mode that it can stick with throughout the animations.

I often use jQuery for quick, simple UI animation jobs, and so I would often do something like this:

$(‘body’).css(‘opacity’, 0.9999);

This nicely prevents the text dimming effect in Firefox 2. So job’s a gooden, right?

Enter stage left: Internet Explorer 7

One of the other techniques we’re seeing a big uptake in is the use of alpha-transparent PNG images, thanks to native support in IE7. Up until now, developers have had to make use of an awkward filter for PNG transparency in IE6. With healthy adoption rates for IE7, creative use of PNG transparency is definitely on the up.

There is, of course, a snag. IE7 appears to have a bug whereby changing opacity on an image element containing an alpha-transparent PNG causes the transparent sections of the image to turn grey (just like the default IE6 behaviour). You can view this demonstration page in IE7 to see it for yourself. Early betas of IE8 have addressed this, and to be honest you can see why IE7 might flip out a bit if you take an image with variable transparency and then try and adjust the opacity of the entire thing. I think I’d flip out too. But I digress.

The issue here is that if you’ve used something like the code above for setting the opacity for the entire page to something less that 1, any transparent PNGs in the page are going to turn grey in IE7. The solution, of course, is to be more specific in your targeting. As jQuery has some basic built-in browser sniffing, I found it easiest to modify my statement to:

if (!$.browser.msie) $(‘body’).css(‘opacity’, 0.9999);

This would apply the opacity change to everything except IE, which in this instance works just fine as IE is the only browser that appears to have a problem with it. There may well be a better way to target FF2 specifically (update: see some great suggestions in the comments below). If you’re using an IE specific stylesheet with conditional comments, you could correct the opacity change in there equally well.

As so often is the case with cross-browser and cross-platform development, fixing one issue can lead to another. Our job as web developers certainly isn’t easy.