Note:

This is an archived copy of the original 24ways article, “Transparent PNGs in Internet Explorer 6”. This temporary copy is for reference purposes only, and will be removed upon the return of the original article. I am posting this archived copy because as of May 28th, 2008, the entire 24ways.org website is no longer online. For more information concerning other great PNG-display solutions, check out my article CSS Hackz Series: PNG Display Fix for Internet Explorer, which refers to this article. Or, you can contact me here for other concerns.

24 ways

to impress your friends

Transparent PNGs in Internet Explorer 6 by Drew McLellan

Newer breeds of browser such as Firefox and Safari have offered support for PNG images with full alpha channel transparency for a few years. With the use of hacks, support has been available in Internet Explorer 5.5 and 6, but the hacks are non-ideal and have been tricky to use. With IE7 winning masses of users from earlier versions over the last year, full PNG alpha-channel transparency is becoming more of a reality for day-to-day use.

However, there are still numbers of IE6 users out there who we can’t leave out in the cold this Christmas, so in this article I’m going to look what we can do to support IE6 users whilst taking full advantage of transparency for the majority of a site’s visitors.

So what’s alpha channel transparency?

Cast your minds back to the Ghost of Christmas Past, the humble GIF. Images in GIF format offer transparency, but that transparency is either on or off for any given pixel. Each pixel’s either fully transparent, or a solid colour. In GIF, transparency is effectively just a special colour you can chose for a pixel.

The PNG format tackles the problem rather differently. As well as having any colour you chose, each pixel also carries a separate channel of information detailing how transparent it is. This alpha channel enables a pixel to be fully transparent, fully opaque, or critically, any step in between.

This enables designers to produce images that can have, for example, soft edges without any of the ‘halo effect’ traditionally associated with GIF transparency. If you’ve ever worked on a site that has different colour schemes and therefore requires multiple versions of each graphic against a different colour, you’ll immediately see the benefit.

What’s perhaps more interesting than that, however, is the extra creative freedom this gives designers in creating beautiful sites that can remain web-like in their ability to adjust, scale and reflow.

The Internet Explorer problem

Up until IE7, there has been no fully native support for PNG alpha channel transparency in Internet Explorer. However, since IE5.5 there has been some support in the form of proprietary filter called the AlphaImageLoader. Internet Explorer filters can be applied directly in your CSS (for both inline and background images), or by setting the same CSS property with JavaScript.

CSS:

  1. img {
  2. filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(...);
  3. }
  4. Source: /code/supersleight-transparent-png-in-ie6/1.txt

JavaScript:

  1. img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(...)";
  2. Source: /code/supersleight-transparent-png-in-ie6/2.txt

That may sound like a problem solved, but all is not as it may appear. Firstly, as you may realise, there’s no CSS property called filter in the W3C CSS spec. It’s a proprietary extension added by Microsoft that could potentially cause other browsers to reject your entire CSS rule.

Secondly, AlphaImageLoader does not magically add full PNG transparency support so that a PNG in the page will just start working. Instead, when applied to an element in the page, it draws a new rendering surface in the same space that element occupies and loads a PNG into it. If that sounds weird, it’s because that’s precisely what it is. However, by and large the result is that PNGs with an alpha channel can be accommodated.

The pitfalls

So, whilst support for PNG transparency in IE5.5 and 6 is possible, it’s not without its problems.

Background images cannot be positioned or repeated

The AlphaImageLoader does work for background images, but only for the simplest of cases. If your design requires the image to be tiled (background-repeat) or positioned (background-position) you’re out of luck. The AlphaImageLoader allows you to set a sizingMethod to either crop the image (if necessary) or to scale it to fit. Not massively useful, but something at least.

Delayed loading and resource use

The AlphaImageLoader can be quite slow to load, and appears to consume more resources than a standard image when applied. Typically, you’d need to add thousands of GIFs or JPEGs to a page before you saw any noticeable impact on the browser, but with the AlphaImageLoader filter applied Internet Explorer can become sluggish after just a handful of alpha channel PNGs.

The other noticeable effect is that as more instances of the AlphaImageLoader are applied, the longer it takes to render the PNGs with their transparency. The user sees the PNG load in its original non-supported state (with black or grey areas where transparency should be) before one by one the filter kicks in and makes them properly transparent.

Both the issue of sluggish behaviour and delayed load only really manifest themselves with volume and size of image. Use just a couple of instances and it’s fine, but be careful adding more than five or six. As ever, test, test, test.

Links become unclickable, forms unfocusable

This is a big one. There’s a bug/weirdness with AlphaImageLoader that sometimes prevents interaction with links and forms when a PNG background image is used. This is sometimes reported as a z-index issue, but I don’t believe it is. Rather, it’s an artefact of that weird way the filter gets applied to the document almost outside of the normal render process.

Often this can be solved by giving the links or form elements hasLayout using position: relative; where possible. However, this doesn’t always work and the non-interaction problem cannot always be solved. You may find yourself having to go back to the drawing board.

Sidestepping the danger zones

Frankly, it’s pretty bad news if you design a site, have that design signed off by your client, build it and then find out only at the end (because you don’t know what might trigger a problem) that your search field can’t be focused in IE6. That’s an absolute nightmare, and whilst it’s not likely to happen, it’s possible that it might. It’s happened to me. So what can you do?

The best approach I’ve found to this scenario is

  1. Isolate the PNG or PNGs that are causing the problem. Step through the PNGs in your page, commenting them out one by one and retesting. Typically it’ll be the nearest PNG to the problem, so try there first. Keep going until you can click your links or focus your form fields.
  2. This is where you really need luck on your side, because you’re going to have to fake it. This will depend on the design of the site, but some way or other create a replacement GIF or JPEG image that will give you an acceptable result. Then use conditional comments to serve that image to only users of IE older than version 7.

A hack, you say? Well, you started it chum.

Applying AlphaImageLoader

Because the filter property is invalid CSS, the safest pragmatic approach is to apply it selectively with JavaScript for only Internet Explorer versions 5.5 and 6. This helps ensure that by default you’re serving standard CSS to browsers that support both the CSS and PNG standards correct, and then selectively patching up only the browsers that need it.

Several years ago, Aaron Boodman wrote and released a script called sleight for doing just that. However, sleight dealt only with images in the page, and not background images applied with CSS. Building on top of Aaron’s work, I hacked sleight and came up with bgsleight for applying the filter to background images instead. That was in 2003, and over the years I’ve made a couple of improvements here and there to keep it ticking over and to resolve conflicts between sleight and bgsleight when used together. However, with alpha channel PNGs becoming much more widespread, it’s time for a new version.

Introducing SuperSleight

SuperSleight adds a number of new and useful features that have come from the day-to-day needs of working with PNGs.

Download SuperSleight

Implementation

Getting SuperSleight running on a page is quite straightforward, you just need to link the supplied JavaScript file (or the minified version if you prefer) into your document inside conditional comments so that it is delivered to only Internet Explorer 6 or older.

  1. <!--[if lte IE 6]>
  2. <script type="text/javascript" src="supersleight-min.js"></script>
  3. <![endif]-->
  4. Source: /code/supersleight-transparent-png-in-ie6/3.txt

Supplied with the JavaScript is a simple transparent GIF file. The script replaces the existing PNG with this before re-layering the PNG over the top using AlphaImageLoaded. You can change the name or path of the image in the top of the JavaScript file, where you’ll also find the option to turn off the adding of position: relative to links and fields if you don’t want that.

The script is kicked off with a call to supersleight.init() at the bottom. The scope of the script can be limited to just one part of the page by passing an ID of an element to supersleight.limitTo(). And that’s all there is to it.

About the author

Drew McLellan is Senior Web Developer and Director at UK-based web development agency edgeofmyseat.com. He holds the title of Group Lead at the Web Standards Project, and likes to bang on about microformats whenever the opportunity arises. When not publishing 24 ways, Drew keeps a personal site covering web development issues and themes.

Responses

Got something to add? Post to your own site and tag it 24ways07 and drewmclellan to be included here.

Your comments

  1. § Dan Ott:

    First off, hurray for 24ways back again! Just another reason to love this time of year.

    Second, great first post, Drew. Transparent PNGs have always been one of those things that really make me hate ie6, and I’ve tried (as have everyone else, I’m sure) many ways to deal with it. This seems like a pretty kick-ass solution; I’m looking forward to trying it out.

  2. § Grégory Karékinian:

    Wow, thanks a lot, finally a working solution! And for some reason you posted this article mere seconds before a project of mine went live. Thanks again.

  3. § Mark:

    I wish this had come along about a month ago when I was working on two projects that were heavy with alpha transparency effects over changing backgrounds!

    As you have very nicely summed up the ideal approach on the implementation side of things, I’m wondering what your recommendation is for processing the PNGs after saving them from Photoshop? I was using GammaSlamma on the mac, but became concerned that it was only stripping the color profile (the primary goal for me, as that was visibly a problem in Safari vs. Firefox), and that other metadata was causing IE to crash.

  4. § Bryan Peters:

    Day 1 and you’re already tackling one of the biggest browser challenges this decade. Can’t wait to see what else you have in store for the other 23 days.

  5. § Nathan Pitman:

    I’ve been using a solution called ‘IE PNG Fix’ (http://www.twinhelix.com/css/iepngfix/) which was written by Angus Turnbull at Twin Helix. It still suffers from the same issues though. I’ve never dissected it’s source code but I assume it’s essentially doing the same thing. :)

  6. § Elbert Oh:

    Often times “position: relative” alone won’t save you. Ingo Chao describes his workaround for this: http://www.satzansatz.de/cssd/tmp/alphatransparency.html

  7. § Ingo Chao:

    position:relative does not trigger haslayout. haslayout is involved, but at a preceding step: The filter does solely apply to elements that have “layout”. This is the reason why your script actually does not work for non-layout elements having a background png, say a simple div with some text in it, without a dimension. You would have to apply a haslayout trigger like zoom:1 for such blocks not already having layout. Links that do not work can be addressed by z-index/position:relative for the link, but not if the element with the filter is positioned. There is a workaround for this situation. http://www.satzansatz.de/cssd/tmp/alphatransparency.html

  8. § Dustin Diaz:

    Super! It’s great that you’ve got scaling working, and the script is very well written too.

  9. § Jay Phillips:

    Oh, I do love this time of year! Another christmas, another 24 ways :)

    Thanks for the great article, I’ll definitely be checking out SuperSleight as I’ve experienced the links-not-working-thanks-to-AlphaImageLoader problem several times myself.

    Thanks Drew!

  10. § Aaron Pepper:

    Thanks for the article Drew, the way IE handles PNG’s is pathetic. I have been looking for an elegant solution like this for a while and Ill definitely be using supersleight for future projects.

    Another thing that I’ve noticed is that IE7 renders PNG8 images with the color slightly off. I don’t think there is a fix for this so it’s best to stay away from them.

  11. § troyb:

    This is a great update! I’ve been sharing both sleight and bgsleight with my students since inception. The scripts have saved many students from pulling their hair out! Now they no longer have to wade through and make sense of all of the comments related to the initial post at Drew’s allinthehead blog. Nice work. Thanks for the gumball mikey!

  12. § Jim Amos:

    One workaround for links becoming unclickable, that I think is worth mentioning:

    If you want an image to repeat, using sizingMethod=“scale”, you can actually get away with it if you use a 1×1 pixel image – that won’t cancel the clickable areas on top, in most instances. Sure, this is not an ideal fix, but may come in handy – it’s worked for me a number of times, for example, adding a dropshadow repeated graphic. There’s something about the 1×1 pixel dimension that allows it to work, don’t ask me why.

  13. § Jake Archibald:

    For the interactivity thing, rather than giving links position:relative, apply it to an element that’s a parent of the links but a child of element with the PNG. If you need to slap in an extra div or something to make that possible, it’s probably worth it.

    Oh, if you create your PNGs in Photoshop or any other editor that doesn’t let you omit gamma info, run them through PNGCrush or PNGGauntlet to prevent colour differences in browsers.

    One final thing, if you’re using PNGs to give an element a single colour but semi-transparent background, don’t use a 1×1 pixel image else it’ll display differently in Safari 2.

  14. § Trevor Davis:

    I still think the Dean Edwards IE7 scripts are the best solution to PNGs in IE6 and below. You just have to have the image end in “-trans.png” (but you can change the suffix if you want). Not only do these scripts address the PNG issue, but also a lot of other IE bugs.

  15. § Martin:

    My new favourite technique for alpha transparency is the use of PNG 8 graphics created with Fireworks which apparently is the only graphics package to export them according to spec. Proper PNG 8 images give you nice alpha transparency for nice browsers and index transparency for the others. In other words, a hack-free, single image solution that degrades gracefully. Check out this article: PNG8 – The Clear Winner

    Obviously, if you absolutely require alpha transparency for IE6, this is not for you but in this day and age I think simple index transparency is good enough for IE6 users out there.

  16. § Paul Campbell:

    Looks like a great fix to me, clean, quick and most importanly avoiding the evil behaviour() application of some previous fizes. I’ve also had a pop at writing my own solution as well, but in the form of a jQuery plug-in. So if you’re a jQuery user/lover please take a look at my png-fix article, it might of use for some :o)

  17. § John Hunt:

    You’re better off not using hacks if you can avoid them. It’s worth pushing to find a way to avoid them too. All too often in the past I’ve had them cause more problems. Still, nice hack!

  18. § Edd Bignell:

    I’m a bit late to this christmas party, but hey…

    Having recently battled with png transparencies and positioned elements containing links in IE6, I found that by actually cutting a hole in the png where you wanted focus (eg. where the input field will appear on the rendered page) let the cursor through the “AlphaImage Barrier”.

    Obviously this is only going to be good for fairly static layouts, where the element that you want to interact with is of a fixed width, height and position relative to the containing element and would be a pain if it was required for more than a few images – but it worked for me!

  19. § Ron Stewart:

    Having played with this, and encountered a wee bit o’ oddity, I have a question about the “applyPositioning” logic. In the current supersleight implementation, that logic is applied to all A and INPUT elements with their style.position === ‘’ — but shouldn’t the logic that sets their position to ‘relative’ really just be restricted to those A or INPUT elements with a backgroundImage property that is indicative of a PNG (based on the file extension)?

    (I ask because I ran into this when I first deployed supersleight, in that it was pushing around the background images on several A elements within my layout that were using GIF images for their background. I solved it by moving that if check up inside the logic that is applied when an element with a background PNG is found.)

    Having asked all of that, however, thanks for writing this. Great hack!

  20. § Drew McLellan:

    Ron: The problem doesn’t just affect links with a PNG background image, but also links with an ancestor element with a PNG background image, or even links that interact with another such element due to positioning. That’s why the applyPositioning routine runs across all links.

  21. § jonathan:

    drew, i wish you had written this article a couple years earlier. i found out about the unclickable links problem the hard way…i’ve still got a bruise from banging my head against my desk. it’s good to hear someone who knows what they talking about say that problem “cannot always be solved.”

    thanks for writing.

  22. § Adrian:

    Great article, very informative. However, I’m still learning, but there as been few times where I couldn’t find ways to use transparent gifs in place of pings. Should we sacrifice page-load for ping superiority when <a href=“http://www.w3schools.com/browsers/browsers_stats.asp”>33%</a> use IE6, and many still use dial-up? I look forward to the day when IE6 is long gone, gifs are obsolete, dial-up has been abolished, and perhaps pings have the ability to be animated…

    Drew, any thoughts on Alex’s <a href=“http://www.sitepoint.com/blogs/2007/09/18/png8-the-clear-winner/”>PNG8</a> article?

  23. § Felipe:

    @martin : Great technique and article, a precision though: pngnq also creates those PNG-8 with alpha layer and it’s cheaper than Fireworks (sure, it’s open source). ErieStuff details how to install it under Windows.
    You can then minify every PNG you create with OptiPNG (with -o7 option, it’s slow but you’ll do it once and the image will be read thousands of times), whether it’s created with Fireworks, pngnq or whatever.

  24. § Schmelding:

    Totally. Awesome. Script.

    - but –

    I added…

    ||obj.tagName==‘TEXTAREA

    …after

    ||obj.tagName==‘INPUT

    because it wouldn’t let me do text entry in a textarea field. I haven’t tested it, but I suspect it would do the same with <select> drop downs.

    Thanks!

Commenting is closed for this article.

24 ways: day 1