How to Use PNGs to Make Awesome Backgrounds
After IE 7 came out with 24 bit PNG support, I really wanted to figure out how to use PNGs better in my designs. However, the 50-60% of people still using IE 6 just didn't seem to justify going in new directions with PNGs. I knew you could make PNGs work in IE 6, but I always thought it was difficult and buggy. Well, as I found out, its not as hard as I thought. This tutorial will show you just how easy it is and how you can do things with your designs that are impossible without PNGs. I assume you have a pretty good knowledge of css, and will be able to use the source code of the examples as a tutorial.
I'll start off with the examples. Click here to see the most awesome use of PNGs for backgrounds ever. Don't blame me if your eyes pop right out your head ;)
As you can see from the examples the big deal with using PNGs is that you can mix two or more background 'effects'. All of the examples utilize a gradient fade in a background div, along with a gradient fade around the square that represents where the page content would go. Examples 2 and 3 throw a pattern on the body background and mix all three images seamlessly. As far as I know, there is no other way to do this with centered page content, a fade around the content, and a pattern in the background that is not horizontal stripes.
So how is it done??
Read on to find out...
Actually, it's really easy. Simply build your page for FireFox and IE 7, and then retrofit it for IE 6.
There are only 4 styled tags in the examples above: body,div#page,div#inner,div#fade. Here is their css for example 3:
body {
background:#DE0C6D url(../../images/png-tutorial/bg3.gif)
font-family:"Trebuchet MS",tahoma,arial,sans-serif;
color:#666;
font-size:.8em
}
#page {
background:url(../../images/png-tutorial/bg-page3.png)
padding:50px;
height:350px;
width:350px;
text-align:center;
z-index:20;
position:absolute;
left:50%;
margin-left:-225px;
}
#fade {
position:absolute;
width:100%;
height:200px;
background:url(../../images/png-tutorial/bg-fade.png) repeat-x;
top:0;
left:0;
z-index:10;
}
As you can see the code is really straight forward for our newer browsers. I'm using a div to hold the fade, and div on a layer above that one to hold the page content. If you didn't want a fade on your background, then you wouldn't have to do the fancy layering and absolute positioning.
Now see how to make it work in IE 6...
Now for IE 6, take a look at the source of the page. You'll see this code in the head:
<!--[if lte IE 6]>
<style type="text/css" >
* html #inner {
background:none;
padding:50px;
height:350px;
width:350px;
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src='../../images/png-tutorial/bg-page1.png', sizingMethod=scale);
}
* html #fade {
background:none;
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src='../../images/png-tutorial/bg-fade.png', sizingMethod=scale);
}
#page {
background:none;
padding:0;
}
a {
position:relative;
z-index:1;
}
</style>
<![endif]-->
Let me explain what is going on here. We are using IE conditional comments to only use this css if the browser is IE 6 or less. If we are using IE then we set the background of the #inner div and #fade div to none, and use the AlphaImageLoader filterto display a PNG. Some tricks to using the AlphaImageLoader are to use the '* html #div' syntax and place the code on the page and not in a css file. I don't know if these are required to make it work (in fact I've see other people do exactly the opposite), but this is the only way I've gotten it to work in every case.
Now if you are paying attention, you might be asking yourself, "Why the inner div?". Well, not only does IE provide the AlphaImageLoader filter, they also provide a nice bug to go along with it. When you apply the filter to an absolutely positioned element (like if we would have applied it to the #page div) then none of the links in #page div's children would work. This is because the AlphaImageLoader filter is placed on a layer above the links. I still don't really get that though, because you can still see the text, but that is how it was explained here. The fix is to apply the filter to a div inside the absolutely positioned element, and then set the links to have position:relative and a z-index of one.
Ok, so maybe that part is a bit confusing, but all in all, if you know these things up front then designing with PNGs is much easier. Here are the links that are mentioned in this post for easy reference: