http://stilbuero.de Klaus Hartl – Stilbüro - Klaus Hartl


Jump to: Search, Additional Information.


PNG alpha transparency, fast and easy

Here’s another “fast and easy” installment: I wondered today, how to add PNG alpha transparency support to Internet Explorer the easiest way possible, without longish scripts and instead easily maintainable in a style sheet . This is not meant to spoil anyone’s good work and as you can see, the basic technique wasn’t discovered by me. It’s just an alternate and hopefully easier way to do it.

An accordingly transparent PNG image, a transparent GIF image (Ugh, I thought I’d never had to use these again…) and the following snippet is all you need.

EOMB will render your beautiful PNG with the following, very simple HTML:

<img class="png" src="/path/to/your.png" alt="different story" />

IE needs to get some special treatment:

img.png {
    background-image: expression(
        this.runtimeStyle.backgroundImage = "none",
        this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "', sizingMethod='image')",
        this.src = "/path/to/transparent.gif"
    );
}

Though I said I wanted to avoid longish scripts, JavaScript (in disguise of Dynamic Properties) is still necessary.

this.runtimeStyle.filter = ... is to apply the appropriate filter for loading and rendering your PNG correctly. Note that the path to the PNG is read from the img element’s src attribute via this.src, so that when you have to change the path you do it once and only once in your HTML source and can leave the rest as supplied before. That’s why I used an expression for this at all and not simply the filter property.

The next expression replaces the PNG with the transparent GIF image so that the same PNG displayed by the AlphaImageLoader filter one level below shows up. This has to be done after we have passed the value of the src attribute to the filter.

Do not omit the first expression, although it seems useless! You would throw IE into an infinite loop loading the GIF over and over again. Don’t ask why, please… Even though I don’t like IE I don’t want to make it hang.

Important: IE 7 has native PNG alpha transparency support. You should use Conditional Comments to include the above style sheet in one or the other way (besides that your style sheet wouldn’t validate):

<!--[if lte IE 6]>
...
<![endif]-->

Some final notes:

  • Of course you don’t have to rely on the class name "png". It’s just an example. You can use whatever selector you wantIE lets you use.
  • If there is no JavaScript, IE simply renders your PNG image without alpha transparency.
  • If JavaScript is turned on, but ActiveX not, you’ll get nothing.
  • The AlphaImageLoader filter is supported in IE 5.5+/Win.
  • A little demo is here.

24 Comments

Comments feed

  1. finally something i can even understand and apply. :) thanks, ma

    Comment by kosmar, March 16th, 2006 at 12:05 pm

  2. hey hey, just tried your fix yesterday and noticed that it doesn’t seem to work in quirks mode. however it’s a nice and easy way to get lost of one of ie’s handicaps…cheers, rh

    Comment by Rioo, June 8th, 2006 at 10:29 am

  3. I was wondering if it would be possible to read the path from a previous background declaration. this would let the behavior be more reusable and if you get the background correct in mox / ff the path could be extracted and used in the expression.

    Just my $.02

    Comment by abba bryant, June 28th, 2006 at 7:12 pm

  4. Author Comment

    Abba, I’m not sure if this could work. I once used the AlphaImageLoader filter (instead of a background image) on elements that contained some links and the result was that these links weren’t clickable anymore.

    But I agree with your $.02 and will try to work something out…

    Comment by Klaus, June 29th, 2006 at 12:13 pm

  5. can this also be applied to backgroudimages plus position them like

    .mydiv {
    background:url(the.png) no-repeat 200px 200px;
    }

    i wonna avoid to crate a div in the div ;)

    thanx christof

    Comment by christof haemmerle, September 30th, 2006 at 8:21 am

  6. I´m trying to get this for the background of a simply div, but in IE my div has no background.

    
    .png{background: url('images/logo_windows.png');   }
    
    * .png { /* use Star Selector Hack here to exclude IE 7 - with the Conditional Comment [if lte IE 6] it didn't work, WTF?! */
                    background-image: expression(
                        this.runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.src + '", sizingMethod="image")',
                        this.runtimeStyle.backgroundImage = 'none',
                        this.src = 'transparent.gif'
                    );
    }
    

    What am I doing wrong?

    Comment by Taote, December 19th, 2006 at 8:54 pm

  7. Author Comment

    You are doing a few things wrong. See, my solution is based on an img element. If you use a background image there is no this.src and you have to get the source from the computed style.

    Something along the following lines could work:

    * html .png {
        behaviour: expression(
            this.runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.runtimeStyle.backgroundImage + '", sizingMethod="image")',
            this.runtimeStyle.backgroundImage = 'none'
        );
    }

    Comment by Klaus, December 19th, 2006 at 10:49 pm

  8. You got it wrong a bit. First you have to remove the bg image and then use filter otherwise browser hangs (at least for me):

    this.runtimeStyle.backgroundImage = ‘none’

    than

    this.runtimeStyle.filter = ‘progid:DXImageTransform.Microsoft.AlphaImageLoader(src=”‘ + this.runtimeStyle.backgroundImage + ‘”, sizingMethod=”image”)’,
    this.runtimeStyle.backgroundImage = ‘none’

    Also I had to use currentStyle object property because runtimeStyle was empty. You have to also keep in mind that .backgroundImage contains full value of background-image property (including url(” …). Therefore you have to get rid of it to properly submit image url to filter. Before none’ing the:
    this.currentStyle.backgroundImage
    you have to preserve it’s value to a var:
    bg = this.currentStyle.backgroundImage
    so you can extract image url later on.

    Hope this helps.

    Comment by snf, January 28th, 2007 at 10:03 pm

  9. There is a simpler solution which doesn’t require JavaScript. It works for both inline PNGs and background images, and lets you fix for IE any image or block element with the addition of a single class. Same as yours, one can use expression() and DX alpha transparency filter, and SRC or BACKGROUND-IMAGE of the affected element, but runtimeStyle is not needed at all. The technique is illustrated at ie-png-transparency.htm and I have just discovered it. It’s two simple style rules (one for background image and one for inline) which will work for any number of PNGs on a page. It works in IE5.5+ and fails gracefully to fully opaque PNGs in IE5.0

    Comment by Yuri Shoroxof, February 2nd, 2007 at 1:00 pm

  10. Author Comment

    Yuri, as long as you use expression() it requires JavaScript turned on (because it’s nothing else than little JavaScripts snippets that get evaluated in the style sheets).

    Comment by Klaus, February 2nd, 2007 at 1:53 pm

  11. This is a great hack under normal circumstances. Thanks for sharing!
    I am encountering a problem though in IE6 with images that get dynamically loaded by javascript (jQuery). The images just don’t show, even if they are not png’s.

    Here’s my code which dynamically loads an image into an image tag with an ID=”myImage”:

    $(’#myImage’).attr({src: imgLoader.src, alt: imagetitle[activeImage], width: imgLoader.width, height: imgLoader.height}).fadeIn(”slow”);

    Here’s the tag:

    And here’s the CSS I used:

    .theImage { /* use Star Selector Hack here to exclude IE 7 – with the Conditional Comment [if lte IE 6] it didn’t work, WTF?! */
    background-image: expression(
    this.runtimeStyle.filter = ‘progid:DXImageTransform.Microsoft.AlphaImageLoader(src=”‘ + this.src + ‘”, sizingMethod=”image”)’,
    this.runtimeStyle.backgroundImage = ‘none’,
    this.src = ‘blank.gif’
    );
    }

    It works if the images are not dynamically loaded, so I’m assuming it has something to do with the firing of the CSS – or rather not firing after the page loads.

    Can you think of a fix?
    Much appreciated and thanks again.

    Comment by Julian, February 8th, 2007 at 2:06 am

  12. Author Comment

    There’s a document.recalc() method, which causes all expressions to be reevaluated. You could try to call this after the image has been changed.

    I saw you were using fadeIn for the image, maybe this could also be the problem – I think I’ve read something like this on the jQuery mailing list.

    By the way: Conditional Comments are special HTML comments, thus they don’t work inside of style sheets of course. There was a reason why I was using the * html hack.

    Comment by Klaus, February 8th, 2007 at 8:17 am

  13. hi klaus,

    - first it seemed to work, now it doesn’t. do you or anyone know or
    understand why the following freezes internet explorer (as also noted
    by SNF)? your tipp on the url below works fine, but the bit you posted
    about making this work for background images as well makes IE6 freeze.
    any help appreciated.

    cheers,

    s

    this freezes IE6:


    * html .png {
    behaviour: expression(
    this.runtimeStyle.filter =
    'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.runtimeStyle.backgroundImage + '", sizingMethod="image")',
    this.runtimeStyle.backgroundImage = 'none'
    );

    Comment by schnuck, February 26th, 2007 at 4:53 pm

  14. Author Comment

    I don’t know why it freezes. But in my original solution there was some freezing as well, in the case I left out an expression (it’s in the post). So maybe you can get around that, if you tinker with some additional expression. Sometimes it’s just trial and error in IE.

    Comment by Klaus, February 26th, 2007 at 6:00 pm

  15. You are right this hack needs javascript enabled just tested it.

    I have a slightly different version that works with javascript disabled. Take a look here
    I think the “expression” function is what needs javascript enabled.

    NOTE: The hack I use is limited in that it can only be used for css background images, so Klaus’s script is definetelly more flexible.

    Comment by GiorgosK, March 8th, 2007 at 9:52 pm

  16. [...] you want similar solutions take a look at  Dean Edward’s IE7 PNG transparency script and Klaus Hartl’s PNG alpha transparency they are actually more flexible but they only work when javascript/jscript is [...]

    Pingback by Transparent PNGs in IE without javascript » GeoLand.org, March 9th, 2007 at 1:50 pm

  17. [...] I’ve previously used a complex Javascript solution for this, which resulted in much headache. Klaus Hartl posted a much improved and more light-weight solution on his Blog back in March 2006 – no idea why I haven’t found this [...]

    Pingback by Better PNG Transparency Fix for IE Browser at Axel Segebrecht, March 29th, 2007 at 2:35 pm

  18. This will alllow one to use transparent PNG for a background also, same class for an inline image or a container:

    .trans-png {
    background-image: expression(
    this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=" + (this.tagName=='IMG' ? this['src'] : this.currentStyle['backgroundImage'].split('\"')[1]) + ")",
    this.runtimeStyle.backgroundImage = "none",
    this.src = "img/transparent.png",
    this.width = this.style.width | this.clientWidth,
    this.height = this.style.height | this.clientHeight
    );
    }

    Comment by Yuri, May 14th, 2007 at 4:47 pm

  19. [...] it’s a necessary step in the IE saga. IE7 finally has some cutting-edge technology such as PNG transparency or full CSS2 compatibility. Some say you can even use it as a browser So get it and please have [...]

    Pingback by WebPRO BrightLight » Blog Archive » Internet Explorer 7 is here, August 21st, 2007 at 3:40 pm

  20. Here is something a bit more fancy I found out trying your suggestion:


    img {
    display: expression(
    (/\.png$/.test( this.src.toLowerCase()) ? this.runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.src + '")' : null),
    (/\.png$/.test( this.src.toLowerCase()) ? this.src = '/skins/common/images/spacer.gif' : null)
    );
    }

    Comment by Technophreak, August 26th, 2007 at 5:04 pm

  21. [...] Transparantie: Met transparante PNG’tjes kun je de mooiste website maken, een klein probleempje IE5.5 of 6 kunnen hier niet mee werken. Gelukkig zijn er enkele kleine oplossingen voor, deze zijn in mijn laatste website toegepast. Deze werkt in alle browsers goed. De iepngfix.htc oplossing, goed voor achtergronden. En de perfecte oplossing voor normale plaatjes, via css! [...]

    Pingback by The Three Marketeers » A site’s spine, March 20th, 2008 at 10:42 am

  22. If you are using jQuery lib in your project, this code may help you with the IE version checking and automatically adding styles to img tags with “.png” sources.


    $(document).ready(function() {
    if(($.browser.msie)&(parseInt($.browser.version)<7)){
    $("img[src$='.png']").each(function(){$(this).addClass("png");});
    }
    });

    Comment by Taha Paksu, April 5th, 2008 at 11:06 pm

  23. this script is a life saver, wasnt having much joy with the other fixes around but this is simple and WORKS!!

    Thanks for saving me from a big headache!

    Comment by Brad, April 10th, 2008 at 11:29 am

  24. IE freezing is because of DirectX Filter AlphaImageLoader that block whole browser until image to show is downloaded from internet. This is trival problem when dealing with few images, but this is unacceptable problem when u got lot images. There is second a lessknown solution that uses VML, but it makes download of images twice, and its worser for any animations. In fact PNG24 just sux for IE and its better to use PNG8 for IE6 only rather that using solutions that will freeze IE…

    Read a little about problem with png here.

    http://www.dcomments.com/Ajax/group7435/topic94945.htm

    Comment by wilq32, February 6th, 2009 at 10:54 am



Klaus Hartl – Stilbüro is powered by WordPress, jQuery, XHTML, CSS and me.