Transparent PNGs and Black Borders in IE 8 with Javascript

Internet Explorer is the bane of all Web programmer's existance. Well, IE6 was. IE7 was an improvement, but still not that great. IE8 was a big step forward, and I'm sure IE9 will be even better.

Notwithstanding that we now need 4 sets of conditional style sheets, IE8 still has a major limitation with transparent PNGs.

IE6 simply cannot render the alpha transparency of a PNG-24 image properly. There are some techniques to get around this, and most involve using a 1x1 transparent GIF as an overlay, and using a Microsoft-proprietary "filter" called AlphaImageLoader. The best example I have found is this 24 ways article.

IE6 is on its way out, and IE7 can render the alpha channel, so there's no problem anymore, right? Wrong. If you apply an animation using Javascript and jQuery, such as fadeIn() or fadeOut(), IE creates black space where the opacity exists and refuses to behave. And it's not fixed in IE8. :( Here's an example: I'm working on a project that has light bulbs as graphical elements. The "off" bulb is supposed to appear like so:

Firefox Internet Explorer

bulb off

bulb off IE

bulb on

bulb on IE

My markup was like so:

#lightbulbs .bulb, #lightbulbs .bulb.off {
  background: url('bulb-off.png') no-repeat 0 0 transparent;
  float: left;
  width: 75px;
  height: 75px;
  margin-right: -40px;
}
<ul id="lightbulbs">
    <li class="bulb off"><span>1</span></li>
    <li class="bulb on"><span>2</span></li>
</ul>

So, how do I fix this?

The fix

I could just use PNG-8. But that's not going to cut it here. The semi-transparent bulb and the glow from the "on" bulb will be lost. And I can't use a solid background here either.

This discussion thread has an overview of the various workarounds. Though there's only one that appears to work the best:

  1. wrap the element in a container <div> and animate the container
  2. use the Unit PNG Fix

Unit PNG Fix is a script that uses a 1x1 GIF, just like the other IE6 fix, but it should be applied to all versions of IE.

The working code

So, I revised my code like so:

#lightbulbs .bulb, #lightbulbs .bulb.off div {
  background: url('bulb-off.png') no-repeat 0 0 transparent;
  float: left;
  width: 75px;
  height: 75px;
  margin-right: -40px;
}
<ul id="lightbulbs">
  <li class="bulb off"><div><span>1</span></div></li>
  <li class="bulb on"><div><span>2</span><div></li>
</ul>

Which applies a height and width to the inner <div>, and gives that the background image. I then added this conditional comment in the <head> portion of the page:

<!--[if IE]>
<script type="text/javascript" src="unitpngfix.js"></script>
<![endif]-->

Which target's ALL IE, not just IE6. And now I'm rockin'.

I can't use background-position or background-repeat on any of these elements, which is a bummer. Luckily I'm not doing that for any alpha transparency. If I needed to position it, though, I'd just added extra whitespace in the graphic file itself. Not pretty, but it works.

Has anyone found a better solution?

Comments

santa's picture

great blog

Add new comment