All A-grade browsers support the .png file format. However, IE6 does not support .png’s with transparency (or alpha channel). Microsoft has provided developers with a number of ‘filters’ that add functionality to IE and the one we are after to solve the .png transparency problem is called the AlphaImageLoader. Documentation can be found here: http://msdn.microsoft.com/en-us/library/ms532969(VS.85).aspx
Implementation of AlphaImageLoader is fairly straightforward. It can only be applied to background images. And it’s usage injects a new, psuedo element into the DOM to display the .png, and introduces a few peculiarities to watch out for along the way.
The link to the image asset in your stylesheet must be relative to the document rather than relative to the stylesheet. Using root-relative links sitewide resolves confusion that may come out of this.
element {
background-image:none;
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='/path/to/asset.png');
}
AlphaImageLoader takes three arguments:
enabled= true or false – default is true, false seems useless
sizingMethod= image, crop or stretch – default is image, this will adjust the size of your element to fit the image. Crop and Stretch are much more useful, as your element will retain its dimensions. Crop clips the image to fit the dimensions of the element. Stretch stretches or shrinks the image to fill the borders of the element.
src= ‘/path/to/asset.png’
‘background’ Note that the background in the sample above is set to ‘none’. Because the AlphaImageLoader is introducing a new element behind the actual element it is applied to, we have to set ‘background:none’ or the original, unfixed .png will sit in front of the fixed one.
‘background-position’ does not work. So your background will always cling to top, left. This is problematic when creating sprites whose states are displayed by shifting the background-position on :hover.
‘background-repeat’ does not work. So the common practice of repeating a small slice of an image to cover the entire background of an HTML element will not work either. In many situations, the ‘strech’ attribute of the ‘sizingMethod’ argument can stand in for a graphic that needs to repeat along and x or y axis.
Elements with AlphaImageLoader applied must hasLayout. Give it a width and/or height. See this article for more info: http://www.satzansatz.de/cssd/onhavinglayout.html
Another oddity it introduces is with clickable elements. They aren’t clickable anymore. Giving and element ‘position:relative’ will allow you to regain functionality, but can cause other issues if the AlphaImageLoader is applied to an element that requires absolute positioning. One workaround would be to add in extra containing markup.
In order to deal with .png’s in an img tag, we need to wrap the image in a span (or other element), apply a background to the span, apply AlphaImageLoader to the span’s background, and finally tell the img be transparent.
HTML for img tag
<span id="png-example" class="pngwrapper">
<img width="150" height="150" alt="Png Example" src="/path/to/asset.png" />
</span>
CSS for img tag
.pngwrapper img {
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);
}
#png-example {
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/path/to/asset.png');
}
Two widely used javascript solutions exist that automate the process outlined above. They can be found at: http://homepage.ntlworld.com/bobosola/pnghowto.htm and http://labs.unitinteractive.com/unitpngfix.php
The benefit of using either of the above solutions is that they evaluate your document and automatically apply AlphaImageLoader where appropriate. This can be an ideal solution for situations where the developer cannot predict when a .png will be used, like in a CMS situation.
The downside is that you are traversing the entire DOM in order to find all instances of .png usage, then applying the AlphaImageLoader to each. Since this is a fix solely for IE6, and IE6 is full of memory management problems, this can really be a drain on resources, especially in applications already employing large amounts of javascript.
Both these fixes will apply ‘position:relative’ to the element with the .png … and any child element. This is can be problematic and can produce unexpected results.
Because we only need to fix transparency for IE6, it is good practice to employ another IE specific option. Conditional comments: http://msdn.microsoft.com/en-us/library/ms537512(VS.85).aspx. Put all CSS into an IE specific style sheet, the CSS ‘filter’, needed to use AlphaImageLoader is not valid CSS.
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="/css/ltIE7.css" />
<![endif]-->
The code above will target only Internet Explorer versions lower than 7. Use a similar comment to include script blocks intended only for IE6.
When using .png’s to make create structural elements– containers with transparent backgrounds, rounded corners, etc. –I prefer to target those .png’s manually using CSS. This is less taxing on the browser and introduces fewer inconsistencies. In some situations this isn’t possible and one has to rely on a javascript application of AlphaImageLoader. Either javascript option can be limited to certain elements of the DOM, and if possible, it is preferrable to not just apply pngFix.js to the entire document.
In a lot of situations where using a .png might be the preferable option, some clever rearranging of your markup may allow you to use a .jpg instead. Also a bit of Photoshop trickery may allow you to use a .gif. If there is no perceived visual difference, do it. In addition to a laundry list of issues that .png’s introduce for the developer, they add a great deal of weight to the page and can impede performance in that regard. There are not a lot of compression options for .png’s, and the ones that are out there simply strip the extra header information off the file. Here is a drag and drop .png ‘optimizer’: http://www.leveltendesign.com/blog/nickc/pngthing-v11-previously-pngoptimizer
I started a little project over at http://code.google.com/p/allyourbase/. It is an upgraded and cleaned up version of my baseline.css file. There are also a few handy javascript classes that make use of YUI. Have at it, I hope you find it useful.