Skip to: Navigation | Content | Sidebar | Footer

Weblog Entry

IE8 Still Failing PNG Alpha

May 20, 2010

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:

IE rendering

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.

May 20, 17h

“Ed Catmull and I invented the integral alpha channel in late 1977 at the New York Institute of Technology. I remember the moment very clearly. Ed was working on his sub-pixel hidden surface algorithm for SIGGRAPH paper submission [1]. He was rendering images over different backgrounds using the new technique. I was working with him since I knew where all the interesting background images lay in our file system. We had six of the rare 8-bit framebuffers at NYIT at this time. I would position a background in three of them (equivalently one RGB framebuffer) over which he would render a foreground element. A different background required a new rendering, a very slow process then.

Ed mentioned that life would certainly be easier if, instead of re-rendering the same image over different backgrounds, he rendered the opacity information with the color information once at each pixel into a file. Then the image could be composited over different backgrounds, without re-rendering, as it was read pixel-by-pixel from the file. I immediately said that this would be extremely easy to accomplish, confident because I had written our image file saving and restoring programs. Versions for saving and restoring 8-bit and 24-bit images existed, and I knew exactly the changes to extend the code to 32-bit images. I started right then and by the next morning had the full package, complete with Unix manual pages using “alpha” and “RGBA” terminology, ready for use. All Ed had to do was write the alpha information into a fourth framebuffer. We called it that because composition uses the classic linear interpolation formula aA + (1-a)B [read a as “alpha” (Greek letters are difficult for .htm documents)] where a controls the amount of interpolation between, in this case, two images A and B. I would save the four framebuffers (equivalently, one RGBA framebuffer) into a file with the new code, savpa4. Then Ed or I or anybody could use the newly revised restore routine, getpa, to composite the file image over an arbitrary image already in the framebuffers. getpa could detect a fourth channel in a file image and use it to composite as the image was read from the file. That was it. The integral alpha channel had been born. The “or anybody” is a key phrase: The integral alpha channel severs the image synthesis step from the compositing step.”

The first working, practical real-world alpha channel, implemented in code is 33 years old.


May 20, 18h

Microsoft should be working in updates for IE7 and IE8 for fix this things, not a new version (IE9) that will probably contain new errors.

But this is Microsoft…

Ps.: sorry for my english, Google Translate help me but I think not much :)

Rob says:
May 20, 19h

I tell people this all the time. Never, ever trust any version of IE to do anything right.

May 20, 23h

Dave you already checked that “buggy feature” at the IE 9 Platform Preview?

May 20, 23h

Yeah, I had the exact same problem last year. PNGs with Alpha-transparency inside a slideshow got weird black spots on them whilst fading, even in IE8. Luckily, in my case, it could be fixed by using a progid:DXImageTransform.Microsoft.AlphaImageLoader filter, which works in IE8 as well when using -ms-filter. (See for a jQuery plugin.) Have you tried that, or was DD_belatedPNG the first fix you tested?

Robert says:
May 21, 06h

IE’s CSS filters will jack up PNGs if you try to run them on content with PNGs in it. It’s not just the Alpha filter. It’s all of their filters. To make matters worse, It will jack up your @font-face fonts, too.

I recently did a client site with some tricky Ajax page loads (unontrusively, of course) where the content faded in and out. While the page cross fades, the font looks horrible (seemed to remove anti-aliasing while it was not 100% opaque), and sometimes things like the bar in “A” would disappear, leaving an upside-down “V”, after the fade back in.

Microsoft needs to research how Webkit and Gecko are doing these things (opacity, etc) and learn a good way to implement them in IE9. Filters get the job done and were arguably ahead of their time (we’re just not getting the CSS transitions MS was working on for years); however, the implementation is kludgy to code and makes things ugly if you are trying to be at all innovative. It’s by no means a good solution compared to what is available on other browsers.

Dave S. says:
May 21, 11h

@Keith Lang - 33 years. Wow.

@Webstandard-Blog - I had not, but upon doing so just now, I’m happy to report IE9 appears to fix the problem. (Assuming it’s actually applying the jQuery, which is something I didn’t check.)

@Mathias Bynens - I tried a bunch of things before settling on DD_belatedPNG, but most alpha-enabling scripts use AlphaImageLoader so they don’t fix the problem.

@Robert - seems there’s hope for IE9 after all, see above.

Glass says:
May 21, 16h

You’re too kind sir. The honor was mine. A true pleasure working with you on this!

NICCAI says:
May 22, 20h

Ugg, was hoping this actually was fixed in IE8. Guess not. As you mentioned, it’s a result of a clash with DXImageTransform. I usually see this manifest as a loss of ClearType in IE. The solution usually involved removing the fade or using js to remove the filter attribute‘filter’) after the fade is complete.

Robin Cox says:
May 23, 09h

I have had the same problems with IE8, it seems that IE8 has a really crappy way with javaScript. I also have to use X-UA-Compatible so I can render javaScript like IE7 does.

So we have IE6 whitch is a really bad browser in all aspects, IE7 that can’t handle css correct and IE8 that hates javaScript.

Thank you microsoft!

May 29, 13h

Looks like nobody else has complimented you on the design of Joyent’s new website. It’s simply gorgeous, from code to interface. Excellent work!

Sylvia says:
June 07, 19h

Thanks Dave for sharing your experiences here. I bumped into this problem with PNGs on IE when I added some jQuery effects to a gallery overlay. Whilst your solution was not suitable for my situation (as you said - not perfect) it did help to gain better insight of what was going on and how bad this is addressed sofar. I hope the problem will be solved for IE9 + jQuery and so I can implement fancier effects on galleries.

June 15, 15h

Browser testing is always fun and where one really earns their money in my experience. I wouldn’t say that it made me a better graphic designer. In fact my inner graphic design child is very upset about it. But my CSS “mechanic” skills are better for it.

Brandon says:
June 18, 12h

I ran into this problem and came up with the same solution using DD_BelatedPNG. I never thought to use the X-UA-Compatible to knock IE8 down to the IE7 renderer though! So I just wrote it off.

I’m revisiting this and the ideal solution would be to get DD_BelatedPNG working in IE8. In my research I learned how Microsoft actually made IE8’s VML renderer even worse and practically broken. It’d be really awesome if someone who knows VML well could figure out a solution to bring this IE8.

Fabio says:
August 12, 06h

Works great on IE9.

Oskar says:
September 21, 03h

Ah, IE and transparency. It’s not just PNG transparency it has problems with though - I recently spent days on a total head-scratcher with an embedded swf with wmode=transparent. I also had a javascript timer running to make transitions on a regular basis. Turns out that while all other browsers were fine with this, IE couldn’t cope with a transparent Flash file and actually SLOWED DOWN TIME! i.e. a javascript timer set to 8 seconds was actually firing every 60 seconds or so. I guess swf transparency isn’t handled by the same engine as PNG transparency in IE, but still.

Anyway, thanks for the post. Fingers crossed for IE9.

September 23, 16h

The one good thing I see is that IE9 is fast approaching and many users will be upgrading. The beta is still missing some of the css3 that currently works in other browsers, but it looks like Microsoft is no longer asleep at the wheel. They are at least trying to stay compliant now.