Agile Ajax

Hacking transparent PNG support into IE6 with IE PNG Fix, CSS and jQuery (part 1 of 2)

IE6 Alpha Channel Transparencey Problems

Yesterday's post showed how to hack the :first-child pseudo-class into IE6 with jQuery and CSS. Continuing with that theme, today and tomorrow we'll show how to enable transparent PNG support in IE6 (so your rounded corners don't look like the ones in this picture).

Today, we'll look at an awesome open-source script that will cover 90% of your needs. Tomorrow, we'll cook up some custom jQuery-flavored JavaScript to cover the corner cases.

As with many of my recent posts, my use case is the new Pathfinder web site, which launched last month. We took a pragmatic approach to implementing our new visual design using web standards. We practiced progressive enhancement globally, resorting to hacks and trickery only in browsers that aren't fully standards-compliant. (To be honest, that includes most modern browsers, though IE6 is the biggest problem child by far).

Our game plan went like this:

  1. If possible, implement the desired look and feel across all browsers using only CSS and semantic markup.
  2. When necessary, serve browser-specific styles using CSS filters.
  3. Don't deploy non-semantic markup just to achieve a specific visual objective in non-standards-compliant browsers.
  4. Instead, if only junk markup will achieve the desired visual effect in non-compliant browsers, inject that junk markup via JavaScript.
  5. The result is a site whose visual fidelity suffers only in non-standards-compliant browsers with JavaScript disabled.

IE6 and the problem with transparent PNGs

Transparent GIF images have served the web well, but they force you to choose a single color value and render it 100% transparent. This makes it difficult to, say, create rounded corners that can adapt to any background color. Most sites therefore create a separate set of rounded corner images for each different background color in their design scheme. Otherwise, their rounded corners will end up with an ugly, anti-aliased edge to them - the hallmark of amateurs. The problem isn't specific to rounded corners: The same issue arises with any irregularly shaped image.

The upstart PNG image format offers a big advantage over GIFs: It supports alpha-channel transparency, in which a color can be rendered transparent and variations of that color can be rendered translucent. This enables the creation of irregularly shaped images that can adapt to any background color over which they're placed. Rounded corners can be created once and deployed site-wide. PNG support in the major browsers has grown from spotty to nearly universal over the past several years, but up until IE6, Internet Explorer presented a problem. It would render PNGs, but it would not retain their alpha-channel transparency. The supposedly transparent pixels would be rendered as an ugly shade of grey (see image).

(Other modern browsers, including IE7+, can display alpha-transparency PNG images natively).

IE PNG Fix to the rescue

IE6's lack of transparent PNG support is appalling, but Microsoft does offer a proprietary fix for the same problem: CSS behaviors, which are a non-standard extension to the CSS spec. By applying a special behavior to your PNG images, you can force IE6 to display them with their alpha transparency intact.

Coding this CSS behavior on an image-by-image basis would be tedious. Luckily, developer Angus Turnbull has released an open-source script that can be used to apply the behavior globally: IE PNG Fix. The current production release is v1.0 RC4, but a preview of v1.0 RC5 is also available.

By deploying this script as an .htc file, hosting a blank GIF file and adding a single CSS declaration to your stylesheet, you can get rid of that ugly gray halo around your rounded corners and get IE6 (and even IE5.5) to display them as intended.

Deploying IE PNG Fix is simple. Download and expand the ZIP file and move two files - iepngfix.htc and blank.gif - to your CSS directory. Within the .htc file, you must change the location of blank.gif to an absolute file path, from this:

if (typeof blankImg == 'undefined') var blankImg = 'blank.gif';

... to this:

if (typeof blankImg == 'undefined') var blankImg = '/sites/pfd/css/blank.gif';

The .htc file does all of the heavy lifting, but it would be useless without a pointer to a valid blank.gif file. The .htc file - which is just JavaScript code that leverages some proprietary IE6 methods - will examine any image you throw at it and, if it's a PNG, clone it and restore alpha-channel transparency to the clone. It'll then replace the original image with your blank.gif file and layer the newly alpha-restored clone of the original image on top. If it couldn't get rid of the original image and leave something the same size and shape in its place, the effect would be ruined.

Once you've installed the script and the blank GIF on your server, you just need to point your new behavior at the correct images using CSS. At the bottom of your site's stylesheet, create a selector that applies your new behavior to all foreground images and all elements with transparent PNG background images, like this:

/*
	apply behavior filter only to foreground images
	and to background images whose position is top left
*/
img,
#content #rail .railBlock .header,
#content #rail .railBlock ul.icons li {
	behavior: url(/sites/pfd/css/iepngfix2.htc);
	}

It's OK to apply the behavior directly to the img tag because the .htc file will check each image to make sure it's a PNG before doing anything.

Voila, your PNGs should look pretty in IE5.5 and IE6.

One small hitch: background-position

Ie_png_fix_backgroundposition_pro_3

There is, however, one drawback to Turnbull's script: It can't account for PNG background images with a background-position other than top left. It will restore the alpha-channel transparency to such images, but it will reposition them to top left, potentially making your designs look even worse than they would have with an ugly gray halo where the transparency should be.

That's what happened on the Pathfinder website (see second image). We had two nested containers, one with the top right rounded corner as its background image and one with both of the bottom rounded corners in its background image. IE PNG Fix correctly restored the transparency of both images. But for the bottom image, which was positioned at the bottom of its container, IE PNG Fix moved it to the top of its container, causing it to display behind the other background image (and leaving a big gap where the image was supposed to display).

You could hack together some JavaScript to account for this deficiency, but you'd probably need to hard-code the math on an image-by-image basis. I'm pretty certain that if it were feasible to automatically calculate the correct position for such images based on the browser's computed styles, Turnbull or somebody else would have done so by now.

Luckily, there's an easier fix, and that will be the subject of tomorrow's post.

Topics: , , ,

Comments: 10 so far

  1. thank you so very much for making this beautiful and simple walthrough to this horrendous problem.

    Comment by Eric, Thursday, April 10, 2008 @ 8:59 pm

  2. I’m glad you found my script useful!

    Yeah, sadly the MS filter doesn’t support background-position or -repeat. The v1.0RC5 script will stretch the image to cover the element when repeat is specified. Perhaps in future I’ll add a separate component to create many nested elements to “mimic” a repeating background where required.

    Also, if you could just link to the main IEPNGFix page on my site that would be great — the /test/ folder is liable to vanish at random moments :). The main page links to both versions for download currently.

    Cheers - Angus.

    Comment by Angus Turnbull, Friday, April 11, 2008 @ 12:54 am

  3. I created a cleaned up and enhanced version of the original PNGFix that also supports background-position: http://gedankenkonstrukt.de/?action=show;id=58
    It’s not thoroughly tested yet, but it seems to work.
    Also, it doesn’t rely on jQuery.

    Comment by Thomas Wittek, Friday, April 11, 2008 @ 6:14 am

  4. Useful. Thanks.

    Comment by Libor Fikr, Friday, April 11, 2008 @ 10:35 am

  5. Thanks, this works great on my main site, so I know I’ve got it working. But do you know if there are any issues that would stop it from working when accessed from another site?

    In other words, I have a wiki at wikidot.com. I have no way to put the .htc file and blank .gif on the server that is hosting the wiki, so I am trying to use them on my main domain. So in my wikidot CSS, I put:

    img {
    behavior: url(http://www.mydomain.com/CSS/iepngfix.htc);
    }

    …which should cause it to execute the code that is on my main site, but this doesn’t work at all.

    Comment by Stephen, Sunday, April 27, 2008 @ 10:43 pm

  6. @Stephen

    I’m not sure whether HTC files can be accessed across domains. They are, after all, JavaScript files, so XSS security protections may prevent them from being executed across domains. A quick Google search on the topic didn’t turn up a definitive answer, but that may be your problem.

    The other problem is that the HTC file on your main domain no doubt points to a blank.gif file that is hosted on that main domain. I’m assuming it has a file path without a protocol or a domain, for instance:

    /img/whatever/blank.gif.

    You’d need to change this to:

    http://maindomain.com/img/whatever/blank.gif

    Either or both of these problems could be preventing your solution from working on your wiki.

    Comment by Brian Dillard, Monday, April 28, 2008 @ 9:30 am

  7. http://www.comesolvego.com/2008/05/02/the-quickest-css-hack-fix-for-ie/

    Comment by vpetreski, Friday, May 2, 2008 @ 7:17 am

  8. What about Dean Edwards’ IE7.js and IE8.js libraries? They purportedly fix all PNG transparency issues in IE. Have you had any luck with those? I included the IE7.js library on one page I worked on and they seemed to do the trick.

    Comment by Jonah Dempcy, Tuesday, May 6, 2008 @ 9:56 pm

  9. @Jonah Dempcy: I haven’t used the Edwards libraries but I hear good things about them.

    Comment by Brian Dillard, Wednesday, May 7, 2008 @ 3:55 pm

  10. http://code.google.com/p/ie7-js/

    >The script only fixes images named: *-trans.png

    >Unfortunately, the transparent background image cannot be tiled (repeated) using background-repeat. Nor can it be positioned using background-position.

    Comment by mingfai, Friday, June 6, 2008 @ 12:13 am

Leave a comment

Powered by WP Hashcash

About Pathfinder

  • We design and build extraordinary applications for companies looking to make the next great idea a reality.
  • learn more

Topics

WordPress

Comments about this site: info@pathf.com