-
Featured Columnists
- Faruk Ateş
- Andy Clarke
-
Kris Hadlock
- Designing with Code: Providing Feedback
- Designing With Code: Creating a Resizable Interface
- Designing With Code: CSS Tips and Tricks to Speed Your Workflow
- Designing with Code: Handling PNG Transparency on the Web
- Designing With Code: Collaboration
- Designing With Code: Improving CraigsList
- Designing With Code: How to Create a Tag Cloud
- Designing with Code: RSS
- Designing With Code: Tumblelogging
- Designing With Code: Create a DropIn JavaScript Component
- Designing with Code: Leveraging Your Existing Content
- Designing With Code: Leveraging RSS
- Designing With Code: Converting Forms to Ajax
- Designing with Code: Converting Forms to Ajax, Part 2
- Designing With Code: Monster Mash
- How to Create Dynamic Script Tags for Ajax Components
- Creating a Winning Proposal for Web Projects
- Creating a Web Design Questionnaire
- Using Stylesheets in Flash CS3
- Animating with XML in Flash CS3
- Creating a Full-Screen Web Site with Flash CS3
- Robert Hoekman, Jr.
- Molly Holzschlag
- Sarah Horton
- Miraz Jordan
- Jonathan and Lisa Price
- Catherine Seda
- Dave Shea
- Dave Taylor
-
Table of Contents
- Welcome
- Web Basics
- Publishing on the Web: Putting Files on the Server
- Web Design Process and Workflow
- Project Management
- Mark My WWWord: HTML and XHTML
- Standards Compliance
- Layouts
- Forms
- Meta Tags and Search
- Usability
- Accessibility
- Enhancing Web Page Interaction
- Web Graphics
- Web Page Optimization
- Multimedia
- Content
- Overview of Servers
- Server Programming Basics
- Careers in Web Design
- Tools
- Tutorials
- Intellectual Property for Web Designers
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.
