Cross Browser PNG Transparency

(I wrote this post at my old job. Since IE6 will be around for some time to come, the techniques in use here are still useful going forward as more and more designers are going to want to use Transparent PNGs in their designs. I’m going to add onto this article at some point in the near future to fully flesh out all the possibilities. See PART 2 of this article)

With the announcement that Internet Explorer 7 would have PNG alpha channel support, there was much rejoicing in the web design and development space (okay, at least in my corner of that space.) The ability of the PNG format to present true transparency and variable opacity has been one of the most tantalizing untapped features out there. Anyone who’s ever worked with transparent GIFs for more than ten seconds should automatically know of what I speak- stack two of them or put one on a background that isn’t matched to it and things start to get ugly in a hurry. IE7 looks like it’s finally going to hand out some native PNG goodness. Someone buy Redmond a beer.

I mention “native” support because IE, since 5.5 (which was released 475 years ago, I think) has been able to display PNGs with all the neat bells and whistles. The thing is, to take advantage of that ability developers have had to cross over into a land of nonstandard and somewhat confusing code.

Personally, I shied away from it for longer than I probably should have for that very reason.

All that changed recently as we had a tool tip design for a client that pretty much demanded full alpha PNGs. We looked at the design and thought, “that looks really nice, we should see if we make that work.” It fell to me to make it work in IE6, the target browser for the implementation. We also targeted Firefox to ensure that the styles (as well as the rest of the application) would work on a standards-compliant browser.

As you might have guessed by the fact that there’s a tutorial in front of you, it worked (better than expected actually) and the process was interesting enough that I thought I’d share the experience. I’ve mocked up a few simplified examples that should cover all implementation variations in a way that is easier to digest than the full blown implementation.

Firefox: As a formality, I’ll touch on getting this to work in Firefox… Firefox’s implementation couldn’t be more straightforward. Simply source the PNG you want to use in an <IMG> tag or in a standard CSS background property declaration. Simply insert the image as is or apply that style, the same way you would apply any other style to a suitable HTML Element and voila you’ve got a transparent image.

Internet Explorer: Where the Firefox implementation was straightforward, the IE version is anything but. For starters, if you have any hopes of producing fully standards compliant code and don’t want to use any browser dependant hacks or extensions look away now. The following system uses all sorts of things that folks obsessed with code purity might find distasteful. Personally, while I would love to produce nothing but “pure” standards compliant code (and I do when I can); there are shortcomings on both ends (both in browser compliance and in the design of the specifications themselves) that get in the way.

It’s not something I lose any sleep over.

Simple Image Replacement

Here’s an example:

Our first variation is probably the most straightforward usage of a PNG: inserting a PNG right into the document as an <IMG>. As we mentioned earlier, doing this in Firefox (and any other browser with full PNG support) is as easy as setting the correct SRC attribute and watching the accolades flow in.

<img src="example1_1.png" />

Internet Explorer 6, on the other hand, needs a little trickery in order to get things to work in the way that we expect. For starters, there needs to be some sort of container for the image. This can be a DIV, a TD, a P, etc. Anything that can enclose the image and cascade styles down. I’m going to use a DIV here.

<div id="example"><img src="example1_1.png" /> </div>

The basic idea is this; we have the PNG in place for regular browsers and then use a couple of proprietary Microsoft extensions to fool IE into rendering it correctly. I’ll go through each of the specifics in turn.

Now that we’ve got it put together structurally, it’s time to style it and make it work the way nature intended. Here are the styles that will make this all go:

First, the cross browser styles to set the position and size of the containing DIV and the image size:

#example {
position:absolute;
width:200px;
height:100px;
z-index:1;
left: 50px;
top: 10px;

}
#example img{
height:100px;
width:200px;
}

Pretty basic so far, as you can see. We then need to add the IE specific styles in order to get the whole thing to work in Microsoft’s browser:

#example img{
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);
}

#example{
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’example1_1.png’,sizingMethod=’image’)
}

I’ll go through each of these in detail. The first line sets the Alpha of the image to 0, effectively hiding it from the user. Internet Explorer has a set of Direct X filters that extend CSS in interesting and powerful ways. This is one of the most useful. Here, it takes one argument, “opacity” and a value, “0”, which sets the image to be fully transparent.

Why would we want to hide the image? Keep reading and the beauty (horror?) of this technique will become clear.

The second style, applies the AlphaImageLoader filter to load a new copy of the image we just hid into the containing DIV. It’s that image that will be processed by the DX filter and rendered correctly. Now hiding the image itself makes sense, no?

The AlphaImageLoader filter takes two parameters, the SRC and the sizingMethod. There are three different settings for sizingMethod, we’ll touch on all three as we move through this article. The one I used, ‘image’ is for situations like this where you want to replicate the display of a PNG image that is being displayed inline. We’ll cover images used as backgrounds in the next post on this topic.

One interesting (and important) thing to note about the SRC in the AlphaImageLoader filter is that it’s relative from the rendered document and not from the style sheet. This is just one more reason why root relative links are the way to go…

Another equally important note is that, for the filter to work, the image has to have ‘layout.’ The concept of ‘layout’ is one beyond the scope of this article, but in general it’s a Boolean flag used by IE’s rendering engine to determine how certain elements are handled. For the filter to work properly, hasLayout MUST be set to true. For the sake of this document we’ll just note that adding proper height and width declarations to the image will set hasLayout correctly.

Posted in Web

Leave a Reply

Your email address will not be published. Required fields are marked *