No Mod Required

Archive for the 'png' Category

Did you know- 8 Bit PNG transparency is just like an old school transparent Gif

Don’t believe me? Check it out:

There’s nothing fancy going on there at all. Here’s the full document:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Untitled Document</title>
  <style type="text/css">
  <!–
  #png {
  background: url(sample-bg.jpg);
  height: 200px;
  width: 200px;
  }
  –>
  </style>
  </head>

<body>
  <div id="png">
  <p><img src="png-sample.png" alt="PNG Sample text" width="94" height="50" /></p>
  <p><img src="png-sample.png" alt="PNG Sample text" width="94" height="50" /></p>
  <p><img src="png-sample.png" alt="PNG Sample text" width="94" height="50" /></p>
  </div>
  </body>
  </html>

As you can see, I’m just grabbing the images and dumping them into the doc. This fails in IE4 and Netscape 4.78. It works in everything else Browsercam offers.

This is different than 32 Bit PNG transparency (24 Bit color depth with 8 Bit alpha,) but still a useful thing to know if, like me, you’re transitioning over to PNGs from GIFs for web graphics.

Cross Browser PNG Transparency: Part 2

This is Part 2. See Part 1.

In October, I posted about cross browser PNGs. Since IE7’s adoption rate is glacially slow, the topic is still relevant. That it’s still relevant is also evidenced by the number of referrals I get on this topic- People are interested in doing this stuff.

One thing I didn’t mention the last time and promised to, was using PNGs as background images. This post will go through the two remaining sizingMethod attributes that allow developers to use PNGs as background images that either tile (or in the case of IE6 stretch or scale in ways that can mimic tiling) to fill or are clipped by the containing block level element.

Images used as backgrounds - tiling (and scaling)

If you need to use a thin strip of image to style a component of variable width or height, you need to be able to tile that image. As before, with Firefox, IE7 and other browsers with native PNG support there’s no difference with how you would handle that technique when compared with a regular GIF of JPG. Simply set the background image and allow it to repeat (which is the default behavior :))

Here’s the HTML for the above example

<div id="tile-example">This is a DIV with a semi-transparent, tiling background</div>

Nothing ground-breaking there.

Here’s the CSS.

#tile-example {
position:absolute;
width:200px;
height:200px;
z-index:1;
left: 50px;
top: 10px;
background:url(tile-example.png);
padding:10px;

}

Again, nothing groundbreaking. Native support is like magic.

For IE6, there’s one major caveat. IE6 doesn’t actually support tiling. IE6 supports “scaling.” Which basically means that the image pulled into the object with the filter fills the entire block. If you’re looking to fill a block with a 1 pixel high image that is set to the width of the block (which is exactly the situation I’ve always used this technique) then the below will work for you. If you’re looking to tile an image to fill a variable width background or to fill up a background with a repeating image (think of the typical Geocities site in 1999) then I’ve got nothing for you.

With the above warning out of the way, on with the hows. With IE6 we use a similar technique to the one outlined before, with a couple of key differences.

Sidetracked! Conditional Comments

Since I didn’t mention it before, I’ll do so here. When doing anything specifically for IE, I take advantage of Microsoft’s Conditional Comments. So, for example, when including a style sheet to enable cross browser PNG transparency, I would do so using the following code:

<!--[if gte IE 5.5]>
<![if lt IE 7]>
<link rel="STYLESHEET" type="text/css" href="transparency/ie.css" />
<![endif]>
<![endif]–>

For IE, that reads “If the browser is greater than IE 5.5 but less than IE7, include the following style sheet.” Every other browser reads it as a plain HTML comment, so we can stuff whatever IE specific stuff we want in the IE specific sheet and the rest of the world is none the wiser. That allows me to stay away from hacks (although I’m still know to use the underscore hack from time to time) and allows my main style sheets to validate.

In other words, I hide my shame.

Seriously though, I can’t recommend conditional comments enough. The technique validates and it’s more future proof than relying on hacks (MS has stated that they will support conditional comments going forward.)

Back to the topic at hand

In the above style sheet we have the following CSS declaration:

#tile-example{
background:url();
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/web/samples/transparency/tile-example.png',sizingMethod='scale');
}

Unlike the previous image replacement example where we had to hide the child image and load the parent container with the filtered PNG, here we have to remove the regular background image declaration, setting it to none and then load the parent container with the filtered PNG. The other difference is with the second argument of the AlphaImageLoader filter. Here we set sizingMethod to “scale” which, as I mentioned above, with certain image configurations is the equivalent of setting the CSS background-repeat property to repeat. It’s not really. What’s happening isn’t tiling at all, but stretching of the image to fit the entire container. In the two ways I’ve ever used this technique that didn’t matter- like here where I used it to “tile” a wide, single pixel high image across the entire height of a container or where I’ve used a single pixel, semi-transparent image to fill in the background of a div. If you were trying to tile a png in the strictest sense of the word, this technique would fail.

Images used as backgrounds - crop

This is a situation where you have a larger background image that you want the containing div to crop out as necessary. The size of the image in the below example is 400px by 400px. I’ve added a blue border to the div to show the edges. Click expand or shrink, in the example to see the cropped area change.


Here’s the HTML

<div id="crop-example">This is a DIV with a semi-transparent, cropped background</div>

Here’s the CSS

#crop-example {
position:absolute;
width:300px;
height:150px;
z-index:1;
left: 50px;
top: 35px;
background:url(crop-example.png);
padding:10px;
border:1px solid blue;
}

and the IE specific code:

#crop-example{
background:url();
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/web/samples/transparency/crop-example.png',sizingMethod='crop');
}

As you can see it’s very similar to the previous example, except for the sizingMethod argument, which is here set to “crop.” Crop maintains the aspect ratio of the original image, but allows the container to clip it where applicable.

And that’s that. Feel free to ping me with questions if I’ve lost you anywhere along the way. I’ve done this piece in fits and starts over the past few days so some things could have slipped through the cracks…

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.

(See PART 2 of this article)