Publishers of technology books, eBooks, and videos for creative people

Home > Articles > Web Design & Development > Usability

Web Design Reference Guide

Hosted by

Toggle Open Guide Table of ContentsGuide Contents

Close Table of ContentsGuide Contents

Close Table of Contents

Designing with Code: Handling PNG Transparency on the Web

Last updated Oct 17, 2003.

By Kris Hadlock

If you’ve ever tried to implement transparent PNG files on the Web, you’ve probably found that they don’t work in all browsers. This isn’t a big surprise since different browsers pick and choose what they implement as standards. I’ve always had the most problems with Internet Explorer, especially when working with transparent PNG images in IE 5.5 and 6.0—until the day I discovered CSS filters from Microsoft.

Programmers often use Microsoft’s CSS filters just to add a few design elements to their pages, but they do have some practical uses as well. Although the filters are only compatible with Internet Explorer, that’s fine because other browsers implement transparent PNG files without needing any extra help.

This column will show you how to use transparent PNGs in your Web sites without having to worry about them breaking in earlier versions of Internet Explorer. You can view a live sample of layered PNG images here and download the source code here. The sample uses a JavaScript method, which implements a Microsoft CSS filter to preserve the transparency in the PNG images.

Sample PNG Images

The PNG images that we’ll use in this sample are included in the source code that was provided at the URL in the introduction. You’ll find the individual images in the img folder and the originals in a Photoshop file at the root of the source zip file.

The images are detailed trees that are various sizes and opacities, which makes them appear to be different depths when they’re layered, as you can see in the Photoshop file. In this sample, we’ll take each of these trees and save them out as separate PNG files. In the HTML, we’ll reference each file and layer them to appear exactly as they do in the Photoshop file. The following code shows how the images are referenced in our HTML file.

Referencing the PNG Files

<div style="width: 800px; height: 600px; border: 1px solid #333">
  <img src="img/tree1.png" style="position: absolute; z-index: 3;">
  <img src="img/tree2.png" style="position: absolute; z-index: 2;">

  <img src="img/tree3.png" style="position: absolute; z-index: 1;">
</div>

The div tag is the main container and it will hold the images. The tag includes styles that size the div to a width of 800px and a height of 600px. A solid, grey border with a width of 1px is also added. Within the div, we reference the three images that are located in the img directory. As you can see, each has a style that is set to an absolute position in order to make them overlap each other in the Web page.

After the positioning is set, we’ll use the z-index to set the layer order for the images. This is all the HTML we need to add to our page and it will work fine in all browsers—aside from earlier versions of Internet Explorer. Let's take a look at how to handle that issue now.

Handling PNG Transparency

With the HTML in place, we’ll need to create a new JavaScript file, which we’ll name photoUtils.js and add to a js directory. After the file has been created, we’ll import it into the head of our HTML file with the following code.

Importing the JavaScript File

<script type="text/javascript" src="js/photoUtils.js"></script>

Now that the JavaScript is referenced properly, we can create the method that will handle the transparencies. The name of this method will be handleTransparency and will be called from the body onload event. Following is the method in all its glory.

The JavaScript Method that Handles PNG Transparency

function handleTransparency()
{
  var b = navigator.appVersion.split("MSIE");
  var v = parseFloat(b[1]);
  if (v >= 5.5 && document.body.filters)
  {
    for(var i=0; i<document.images.length; i++)
    {
      var img = document.images[i];
      var imgName = img.src.toLowerCase();
      if(imgName.substring(imgName.length-3, imgName.length) == "png")
      {
        var imgID = (img.id) ? "id=’"+ img.id +"’ " : "";
        var imgClass = (img.className) ? "class=’"+ img.className +"’ " : "";
        var imgTitle = (img.title) ? "title=’"+ img.title +"’ " : "title=’"+ img.alt +"’ ";
        var imgStyle = "display: inline-block;"+ img.style.cssText;
        
        switch(img.align)
        {
          case "left":
            imgStyle += "float: left;";
            break;
          case "right":
            imgStyle += "float: right;";
            break;
          default:
            break;
        }
        
        if(img.parentElement.href) imgStyle = "cursor: hand;"+ imgStyle;
        
        var strNewHTML = "<span "+ imgID + imgClass + imgTitle
          +" style=\""+ "width:"+ img.width +"px; height:"+ img.height +"px;"+ imgStyle +";"

          +"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
          +"(src=\’"+ img.src +"\’, sizingMethod=’scale’);\"></span>";
        img.outerHTML = strNewHTML;
        i-=1;
      }
    }
  }  
}

The method that we’re using looks fairly large, but it’s really just a lot of browser checking and img tag settings that we’ll transfer to a new tag.

We’ll start by checking to see if the browser type is MSIE (Microsoft Internet Explorer) and we’ll use the result to see if the version is less than or equal to 5.5. We’ll also check to see if the filters, which are the style properties we’ll use to set the transparency, are available.

If all of these conditions pass, we’ll iterate through all the images in the document and check to see if they’re PNGs. If they are PNG files, we’ll transfer settings from the img tag to local variables. We’ll then use the variables in a new tag that we’ll create for each of the images.

We’ll copy the id, class, title, style and alignment settings to local variables. This ensures that any time we use this method, the previous settings for every image tag in our document will remain intact.

The last and most important piece of code is the new tag that we’ll create for each image. The tag will be a span and will receive each of the settings that we used previously. The filter that makes it all work is the AlphaImageLoader, which is provided by Microsoft. This filter has an src property, which we set to the image source that we stored away from the original tag.

With this solution, we can create very complex designs in HTML. I recently created a site that had a revolving set of images in the background with a PNG image in the foreground that stayed consistent throughout the animation. I used this technique to set the foreground image to a transparent PNG, with revolving background images saved as JPEGs. Previously, I would have had to use Flash to create this design, but since I didn't have to use any plugins, I created it in good, old Javascript. I hope this gives you some ideas and solves some design problems in your future projects.