PNG tips

February 2nd, 2008

PNG file format is great. It allows you to be creative and draw cool icons and graphics for your applications with 24bit color depth and an 8bit alpha channel to map transparency.
However, when used in the design of web pages it can cause you some troubles.

Here’s a short summary of good and bad things about it.

PRO

  • color depth: up to 48bit, but you will generally use it at 24bit (16777216 colors)
  • quality: PNG uses lossless compression (unlike JPEG)
  • alpha channel: 8bit (256 opacity levels, unlike the 2 levels of GIF)
  • ausiliary information: gamma correction and other useful data is stored into “chunks” embedded in the file (to make the image display correctly on devices different from the one used to create it)

CON

  • internet explorer (versions <7): there is no native support for PNG alpha transparency
  • gamma correction chunk: yes, it’s a big pro, but unfortunately browsers don’t interpret it correctly. As a result, if you use PNG images in combination with other formats (GIF, JPEG…) and/or with pure CSS colors (as a background for example), it can be a source of big inconsistencies in color and luminance

The solution

Alpha transparency problem: the easiest solution should be banning IE from every modern computer.
An alternative and less drastic way involves the use of the infamous Microsoft.AlphaImageLoader filter plus some pure CSS tricks or Javascript.
Remember, these tricks work only with Internet Explorer 5.5 or grater.

Case 1: you want to fix PNG transparency on a css-defined image (i.e. a background image defined in your stylesheet)
with a solution that is relatively clean (meaning that your code will validate and won’t cause error in other browsers).

First, hide the background definition to IE in your stylesheet (suppose it is style.css) by declaring it through a child-selector (the “>” operator).


#header {
width: 720px;
height: 135px;
position: relative;
}/*start hack for IE6*/
html > body #header {
background: transparent url(../images/header.png) no-repeat;
}
/*end hack*/

While it is correctly interpretated by other browsers (that pick the element with id=”header” in the body, which is clearly a child of the html document),
Internet Explorer ignores it because child-selector was not supported until IE7.

Then, create another stylesheet (let’s call it IEpngFix.css) and add the following definition:


#header {
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader (src="images/header.png",sizingMethod="crop");
}

This Microsoft proprietary filter would generate an error in other browsers, so the third and last step is to link IepngFix.css only in IE with version <7.
It can be done using IE conditional comments in your HTML header:


<!--[if lt IE 7]>
<link rel="stylesheet" type="text/CSS" href="css/IEpngFix.css"/>
<![endif]-->

Notes:

  • This solution avoids the use of Javascript and you have total control on what’s happening.
  • If you want to fix an image that is used as a repeated background, instead of the “crop” property you should use sizingMethod=”scale” in the AlphaImageLoader
  • This hack has one major drawback when the image you are fixing is used as a background for anchor elements: links won’t work! So spend some time planning your website if you’re interested in IE full accesibility.
  • It works for 5.5<IE<7.

Case 2: you want to fix a PNG image declared into your HTML into an <img> tag.

The first solution is to use one of the Javascript PNG fixes that you can find around the web (i.e. here).

The second one, is similar to the css solution explained above in the case of images defined within your stylesheet and requires adding the script part to your IEpngFix.css inside an expression():


* html img,
* html .png{
position:relative;
behavior: expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none",
this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "', sizingMethod='image')",
this.src="images/blank.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''),
this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "', sizingMethod='crop')",
this.runtimeStyle.backgroundImage = "none")),this.pngSet=true)
);
}

Note: you must have a transparent gif (in this example “blank.gif”) in your images directory, since it is used as a replacement of the original image that is going to be filtered. If you don’t want to create that image, you can find it in the zip file downloadable at the bottom of this tutorial.

The above solution (that i have found here) works actually with css background images, too:
you just have to add class=”png” to the elements you want to fix.
The only problem is that repeated backgrounds are not allowed, so in that case you have to do it manually as in Case 1.

Gamma correction problem: as you can see in the image below, in this example the color of the PNG image doesn’t match the gray css background, even if you set them with exactly the same RGB values.

To have cross-browser consistency, the only solution is to discard Gamma information (and it’s funny, because Gamma correction exists right to avoid different behaviour between different devices).
You can do it when saving your PNG files directly from your graphic application (Gimp2 as an example) or using a powerful small program called TweakPNG.
With that, you can edit PNG chunks and decide to discard some of them (it’s the program that suggests what’s safe and what’s not).

Download TweakPNG here

That’s all!

Download the sample code of this short tutorial.

Yet Another Web2.0 Images Tutorial

January 16th, 2008

I know, there’s plenty of tutorials like this. But this is a simple quick thing to start from.

If you’re still asking yourself “how can I make those cool images with reflective-shiny-glass-gloss effect?” keep on reading.

There are just a few steps:

1. Download Inkscape

2. Open a new document and draw something (a simple rectangle-shaped button or text, it doesn’t matter). Click on the object you’ve just created and select it: now on the bottom left part of the screen you should see two small rectangles representing fill and stroke colors. Choose a suitable color for both the elements.

3. Select the element and on the menu go to edit > clone > create clone.Now you’ve created not just a copy of the object but a linked clone: this way, changing parameters of the father object will affect its child.This is useful because now you’re going to create the reflection and it will automatically adapt to the changes you’ll apply to the object (try changing the color, opacity or blur and see what happens).Once you have your clone, go to object > flip vertical and translate down the reflection.

4. To make the reflection look better now you have to make its opacity fade from opaque on top to transparent at the bottom.To do this, create a rectangle with approximately the size of the reflection (a little bigger) and fill it with a gradient from white to black.This new shape will be used as a mask: place it over the reflection, select both objects (click the foreground object and then alt+shift+click to select the background object too), then go to object > mask > set.Adjust the opacity of the reflection to some value between 10% and 30% depending on the brightness of the background.

5. Apply a gradient fill to the main object (to make it a little darker on top or bottom, depending on the effect you want to reach).

6. To make your object look polished/shiny go to edit > duplicate and make a copy of it (without moving it, leave it perfectly aligned), then create a white ellipse (or draw the shape you prefer with the pen tool) and place it over the copied object.

7. Select both the objects and go to path > intersection. Adjust the opacity of the shiny reflection and choose if you want to leave it with a solid color fill or a gradient that fades to transparent at the bottom.

8. That’s it! Simple, once you are a little familiar with Inkscape.


9. If you organize your objects into layers and groups, now it’s easy to try another experiment: divide the objects into 3 groups (select all the components and go to object > group), then apply some blur to the different groups in order to simulate a depth-of-field effect (just imagine you are taking a photo and the object in the middle is focused while the near and far ones are not).

Have fun :P

Hello world!

December 28th, 2007

Finally freewally.net is online. Now it’s time to start working on the blog!

In the meantime visit my portfolio