You thought our long nightmare of PNG alpha transparency support was finally over as of IE7, didn’t you? Yeah, me too.
Over the past few months I’ve been collaborating with Chris Glass on the newly-launched Joyent site. (When someone comes to you and says, hey, we have Chris Glass helping us out with this project and we’d like the two of you to work together, you jump at that chance.)
I was tossing around ideas for building an interactive infographic Chris had designed, and thought of at least four different ways of pulling it off. We’re reaching this interesting point with front end web technology where we now have actual choices besides Flash for jobs like this. I considered CSS3 animations and the Canvas element before ultimately deciding on PNGs with alpha transparency and jQuery transitions and fades.
I put off browser testing as long as I could, but just this week prior to launch I realized it was very broken in all versions of Internet Explorer. I had a plan to back out to a static graphic in IE6, assuming IE7 and IE8 would treat the PNG + animation combo like any other reasonably modern browser. I was wrong.
It seems that IE’s implementation of PNGs with alpha transparency is still buggy or incomplete in some way. When you place a PNG with alpha on a static page, you’ll never be the wiser. It’s when you adjust the opacity of that PNG that you run into problems. Take the following example:
I’m overlaying this slightly-transparent image of three triangles atop a few different backgrounds. So far so good. IE7 and IE8 keep up. But if I apply further transparency to the image in the form of a jQuery
fadeIn or an opacity value, things go a little haywire:
That’s the same setup as before, only with an opacity value of 0.99 (almost completely opaque) applied to each
img element. In non-IE browsers, the previous two examples ought to look the same. In IE7 and IE8 on the other hand, the previous example instead looks like this next one:
Of course, no version of IE supports the CSS
opacity property yet, so jQuery instead applies the opacity by exploiting the IE-proprietary AlphaImageLoader filter. This ends up being the root cause of the (seemingly well-known) bug. The suggested fix is to apply the transparency to the parent element instead, but I’ve had little success with that workaround.
What did work was a little library called DD_belatedPNG that applies PNG transparency via VML instead of AlphaImageLoader. It’s designed for IE6, but it works just fine in IE7 as well. For IE8, I was forced to throw out an X-UA-Compatible meta tag and step IE8 down to IE7 mode for this particular page.
It’s still not perfect. I noticed a faint white bounding box poking through at lower opacities that forced me to slightly adjust hover effects for all versions of IE. But you know, for all that, it’s darn well good enough.