No Mod Required

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…

31 Responses to “Cross Browser PNG Transparency: Part 2”

  1. Dave Says:

    Thank you, thank you, thank you.

  2. aequalsb Says:

    re: sizingMethod

    thought you’d like to know this:

    of the 3 sizingMethods:

    image -> sizes the parent container to the size of the src image

    crop -> doesn’t size the parent container (basically to explicitly override the default ‘image’ sizingMethod)

    scale -> STRETCH the image to fill the parent container

    using Internet Explorer 5 - 6 with the AlphaLoader filter and a semi-transparent .png… there is NO equivalent for background-repeat:repeat

    of course, a ‘flat’ semi-transparent .png image (say solid white 25% transparent) using the scale method will appear to tile and fill the container — but in all reality, it is being STRETCHED to fill the container…

  3. rob Says:

    Thanks. I’d never really peaked under the hood at what was happening and in every case where I’d ever used it the behavior was exactly what I would have expected from a tiled image.

  4. Tim Says:

    I have tried the code but don’t know why it is not getting into shape.

    here’s the css for my background tiled png

    #main{
    background: url(../imgs/images/mainbg.png);
    text-align: center;
    width: 916px;
    height:auto;
    margin-top: 0px;
    margin-right: auto;
    margin-bottom: 0px;
    margin-left: auto;
    overflow: hidden;
    }

    and i have put this code in the head section of my webpage:

    this is my ie.css:

    #main {
    background:url();
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’../imgs/images/mainbg.png’,sizingMethod=’scale’);
    text-align: center;
    width: 916px;
    height:auto;
    margin-top: 0px;
    margin-right: auto;
    margin-bottom: 0px;
    margin-left: auto;
    overflow: hidden;
    }

    This will be very helpful if let me know what to do with it. I am also using “img, div { behavior: url(iepngfix.htc); }” i my main css.

    Thanks.

  5. rob Says:

    Do you have a URL I could look at?

  6. shfx Says:

    Like aequalsb said before - its SCALING, STRETCHING, not TILING! Geez.. It makes people confused ;)

    Please correct “tiling” to “scaling” or something equal .

    Best. shfx

  7. rob Says:

    Yeah, I’ll get that section straightened out this week. I thought I updated it, but I obviously never did :)

  8. rob Says:

    updated. Thanks guys!

  9. Doug Says:

    Yeah, I am trying to the best of my ability to take what you’re showing here and implement it into my own situation and it is just not working.

    Can someone give me a hand with this?

  10. rob Says:

    Sure, can you point me to a sample of what you’re trying to do on the web so I can look at your code?

  11. userXt Says:

    Hey guys. Just ran into the same problem here.
    And I’m not getting it to work either….

    please have a look at my website if u can find sth.

    ~Xt

  12. rob Says:

    @userXt

    your doc @
    http://www.userxt.com/2008/
    points to at style sheet at :

    ../styles/indexietransparency.css

    which translates to :
    http://www.userxt.com/styles/indexietransparency.css

    which is a 404

    you simply need to change the link tag to point to

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

    which will translate to:

    http://www.userxt.com/2008/styles/indexietransparency.css

    which is there.

    That might do it.

  13. userXt Says:

    ok now…
    It’s working now… kind of at least.

    Is there any possibility to position the newly-rendered png similar to

    background-position: x y;
    background-repeat: repeat-x;

    Well ok, I read repetition is not possible…
    but the positioning maybe??

    ~Xt

    btw. this is a really useful website!! thanks

  14. rob Says:

    Hi,

    You’re not going to be able to use the same technique in IE6. Looking quickly, what you could maybe do to support IE6 is create a full blown image representing a combination of the banding and the banner and just swap that out for for the banner.jpg missing the banding in your IE sheet. Is there something I’m missing about the design that would stop you from doing that?

  15. userXt Says:

    Well ok…
    I built in the AlphaImageLoader combined with this “IE-or-not-Check” and now I got sth.

    Problem is, that’s only the start page and the rest of it I can’t use the AlphaLoader with, cause I need the repeating background and the positioning…

    Maybe I’ll figure sth. out, let’s see…

  16. karl Says:

    I have been attempting to use a transparent png for a background image, and have tried all sorts of techniques with no luck. Above, you mention scaling a 1px high image for the background, which is what I have been trying to achieve with IE6, and no joy. Can I scale a 1px high png to do give the same result as appears in every other browser?

  17. rob Says:

    got a sample I can look at?

  18. karl Says:

    Thanks for the response.

    Link in my name has a reduction of it: http://www.mothership.co.nz/reduction

    the problem png is: http://mothership.co.nz/reduction/images/bg.png

  19. rob Says:

    Both the PNGs are good candidates for this technique. The logo needs to replaced with the “image” method outlined in part one of this article and the background image of the content div needs to be replaced with the “scale” method outlined here.

  20. karl Says:

    Thanks for the hints.

    I’ll give it a go shortly, so keep an eye out to see how I progress.

    Otherwise I’ll probably be starting out fresh.

  21. rob Says:

    Let me know if you have any problems. I can maybe point you in the right direction quickly if it’s something I’ve seen before (a likely enough occurrence since I’ve used this technique in production a few times.)

  22. karl Says:

    I have replaced the logo with a PNG with a white background, but the background image of the content div refuses to scale (for me at least).

    I have gone over both CSS sheets, as well as the html, and cannot find a reason for this. Frustrating.

  23. karl Says:

    Having worked through this, I don’t believe it will function as I intend. The issue is that the background and #content colours are white, so there is little demarcation between them. Running the script makes the whole PNG transparent, including the white in the middle. I guess at this juncture I will look to change the design somewhat (as tempted as I am to use conditional comments and create an entirely different look for IE users only).

  24. rob Says:

    The white in the middle should remain white as long as the image is produced with white in the middle. If that makes sense.

    All you’re trying to do is have a smooth drop shadow on top of the space ship? that’s definitely possible with this technique. You have two sides which will be semi-transparent and then the middle will be solid white, right? That’s a perfect candidate for the full cross-browser technique.

    the sample I just looked at has background: transparent url(), etc. in the main sheet so I can’t really debug what might be happening in IE6, but this would definitely be possible.

    In your IE6 specific style declaration you would need something like this:

    #content{
    background:url();
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’http://mothership.co.nz/reduction/images/bg.png’,sizingMethod=’scale’);
    }

    Here it is working (only in ie6 for now- the browsers with PNG support need to be worked with using normal techniques.)

    http://www.drunkenfist.com/web/samples/test.html

  25. baker Says:

    Here’s one for you - alphaImageLoader AND alpha(opacity) without the PNG looking like crap?

    I’m in the midst of researching it, and it seems no one has tried (yet) and there is no documentation anywhere about it…

  26. rob Says:

    Hrm, interesting. I’ll take a look at that today. I have some time I can dedicate to research this week and that’s sounds like it will be interesting.

    I can’t even picture what IE6 would do.

  27. karl Says:

    Rob,

    you solved the issue for me, but possibly not in a manner which any of us envisaged. When I had a look at your example, it displayed as intended in IE6 on my test machine. I looked at the source code of your example then went to my page to check the differences. Upon browsing to the page, it rendered as yours did.

    I was confused, until I recalled that IE caches aggressively, and I had actually solved the issue first time I tried the technique you talk about above, but because of caching of the files in question, I was still getting the old page!

    The sample I had I had only linked to the css for <IE7, as the IE6 standalone I had installed considers itself IE7 (standard browser) when reading conditional comments. I have since rectified this with a different standalone version of IE6.

    Thank you for time and effort - much appreciated, and great to see your technique works.

  28. rob Says:

    @baker

    It doesn’t appear to work.

    IE seems to just drop the AlphaImageLoader part entirely.

    I didn’t exhaustively research it, but I did try a couple of approaches.

    Here’s a screen shot.

  29. Nate Says:

    I was having some serious DIV’itis and, while I got my page to markup, what a horrid mess for content management. This worked like a charm, at least IE6 has some PNG support even if only proprietary. Thanks for posting and with clear instructions and explanations. A rarity.

  30. Julie Hathaway Says:

    Fabulous — it worked perfectly on the first try!

    Thank you thank you thank you!

  31. Julie Hathaway Says:

    However, I believe there is a typo in the conditional comment. The last [endif] is missing a hyphen.

Leave a Reply

Note: Wrap all of your code blocks in <code>...</code> and replace < and > with &lt; and &gt;, respectively.