77

I'm having problems with a transparent PNG image showing black dithered pixel artifacts around the edge of the non transparent part of the image. It only does this in Internet Explorer and it only does it from a Javascript file it is used in.

Here's what I'm talking about... http://70.86.157.71/test/test3.htm (link now dead) ...notice the girl in the bottom right corner. She has artifacts around her in IE8 (I haven't tested it in previous versions of IE, but I'm assuming it probably does the same). It works perfectly in Firefox and Chrome. The image is loaded from a Javascript file to produce the mouseover effect.

If you load the image all by itself, it works fine. Here's the image... http://70.86.157.71/test/consultant2.png

How to fix this?

The image was produced in Photoshop CS3.

I've read things about removing the Gama, but that apparently was in previous versions of Photoshop and when I load it in TweakPNG, it doesn't have Gama.

Cœur
  • 37,241
  • 25
  • 195
  • 267
user138777
  • 823
  • 1
  • 8
  • 8
  • 9
    The problem is almost undoubtedly caused because you are applying css opacity (via ie's filter system) ultimately to a png, which would appear to be causing the problem. – meandmycode Aug 09 '09 at 14:05
  • Do you have any suggestions for what to change it to so that it works in IE? – user138777 Aug 09 '09 at 14:55
  • 1
    Correct. Don't use the opacity filter (or any other filters for that matter) as it introduces artifacts. – EricLaw Aug 09 '09 at 15:43
  • I'm using jQuery to fade in the slides - In that case it has to do the opacity fade.. and right now it's all showing up with the black edges. Any way around it? – jeffkee Jul 15 '10 at 23:51
  • Could you accept an answer so I can lock this? This question already has nine deleted answers; its attracting lots of "mee tooo!" and "thanks!" answers. –  Apr 04 '11 at 13:55

10 Answers10

106

FIXED!

I've been wrestling with the same issue, and just had a breakthrough! We've established that if you give the image a background color or image, the png displays properly on top of it. The black border is gone, but now you've got an opaque background, and that pretty much defeats the purpose.

Then I remembered a rgba to ie filter converter I came across. (Thanks be to Michael Bester). So I wondered what would happen if I gave my problem pngs an ie filtered background emulating rgba(255,255,255,0), fully expecting it not to work, but lets try it anyway...

.item img {
    background: transparent;
    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)"; /* IE8 */   
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);   /* IE6 & 7 */      
    zoom: 1;

}

Presto! Goodbye black, and hello working alpha channels in ie7 and 8. Fade your pngs in and out, or animate them across the screen - it's all good.

Dan Tello
  • 1,517
  • 1
  • 10
  • 10
  • i had the same problem, but in my case an white background was enough to workaround it. Thxs for the suggestion – Quamis Dec 23 '10 at 10:57
  • Combining this with the **AlphaImageLoader** hack below on :hover did the trick for me. – nickb Jul 04 '11 at 21:57
  • Thanks - this worked for me, but I needed to add my background to another element as a child of the original element that was being faded .. added details below. – codeinthehole Jul 06 '11 at 14:42
  • 4
    Do note that this appears to be only a partial fix - Explorer still premultiplies the transparent PNG with black. What this means is that if you have, say white section with 50% opacity (in the PNG) and then you apply any kind of opacity (via CSS) to that element, what you'll see is actually GREY (50% white x 100% black) at whatever opacity level you've specified with your CSS. Still looking for a real solution, but haven't found one yet. – Tom Auger Nov 28 '11 at 19:06
  • Thanks! You saved me what I imagine could have been tons of wasted time. – Ben Davis Jul 09 '12 at 16:20
  • assuming the image is a backgroundimage loaded dynamically with javascript? how can i apply this solution? – Ogugua Belonwu Jul 31 '12 at 23:00
  • PS. The first rule did not worked for me on IE8, only the second. – Johnny Everson Sep 21 '12 at 20:52
  • wow thanks, this saved me surfing more of the web to find a solution :D – mic Oct 08 '12 at 12:11
  • 3
    Hi! I may know why it's not working for some of you. In my case, I was animating the opacity with jQuery. But guess what! You can only set ONE filter declaration at a time (even when you can put many filters in that "filter:" declaration). So, when jQuery animates the transparency, it sets a filter, overriding the others. Solution: wrap your image in a div; apply the the alphaImageLoader or gradient filter to the image and animate the opacity of the div. Voila! – Diego Sep 19 '13 at 23:46
9

I put this into a jQuery plugin to make it more modular (you supply the transparent gif):

$.fn.pngFix = function() {
  if (!$.browser.msie || $.browser.version >= 9) { return $(this); }

  return $(this).each(function() {
    var img = $(this),
        src = img.attr('src');

    img.attr('src', '/images/general/transparent.gif')
        .css('filter', "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='crop',src='" + src + "')");
  });
};

Usage:

$('.my-selector').pngFix();

Note: It works also if your images are background images. Just apply the function on the div.

Benjamin Crouzier
  • 40,265
  • 44
  • 171
  • 236
Mike Cavaliere
  • 670
  • 6
  • 10
7

I know this thread has been dead some time, but here is another answer to the old ie8 png background issue.

You can do it in CSS by using IE's proprietary filtering system like this as well:

filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='scale',src='pathToYourPNG');

DEMO

you will need to use a blank.gif for the 'first' image in your background declaration. This is simply to confuse ie8 and prevent it from using both the filter and the background you have set, and only use the filter. Other browsers support multiple background images and will understand the background declaration and not understand the filter, hence using the background only.

You may also need to play with the sizingMethod in the filter to get it to work the way you want.

vitaut
  • 49,672
  • 25
  • 199
  • 336
Fresheyeball
  • 29,567
  • 20
  • 102
  • 164
5

I had the same thing happen to a PNG with transparency that was set as the background-image of an <A> element with opacity applied.

The fix was to set the background-color of the <A> element.

So, the following:

filter: alpha(opacity=40);
-moz-opacity: 0.4;
-khtml-opacity: 0.4;
opacity: 0.4;
background-image: ...;

Turns into:

/* "Overwritten" by the background-image. However this fixes the IE7 and IE8 PNG-transparency-plus-opacity bug. */
background-color: #FFFFFF; 

filter: alpha(opacity=40);
-moz-opacity: 0.4;
-khtml-opacity: 0.4;
opacity: 0.4;
background-image: ...;
Josh Mouch
  • 3,480
  • 1
  • 37
  • 34
4

please try below code.

 background: transparent\0/;
 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='image',src='assets/img/bgSmall.png');   /* IE7 */      
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='image',src='assets/img/bgSmall.png')"; /* IE8 */   
Kevin G Flynn
  • 231
  • 4
  • 14
4

PNG transparency prоblеm in IE8

Dan's solution worked for me. I was trying to fade a div with a background image. Caveats: you cannot fade the div directly, instead fade a wrapper image. Also, add the following filters to apply a background image:

-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='image',src='assets/img/bgSmall.png')"; /* IE8 */   
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='image',src='assets/img/bgSmall.png');   /* IE6 & 7 */      

Please note that the paths in the src attributes of the filters are absolute, and not relative to the css sheet.

I also added:

background: transparent\9;

This causes IE to ignore my earlier declaration of the actual background image for the other browsers.

Thanks Dan!!!

Community
  • 1
  • 1
Andrew
  • 3,332
  • 4
  • 31
  • 37
2

Dan Tello fix worked well for me.

One additional issue I found with IE8 was that if the PNG was held in a DIV with smaller CSS width or height dimensions than the PNG then the black edge prob was re-triggered.

Correcting the width and height CSS or removing them altogether fixed.

zeniph
  • 21
  • 1
2

I use a CSS fix rather than JS to workaround my round cornered layer with transparent PNG inside

Try

.ie .whateverDivWrappingTheImage img {
background: #ffaabb; /* this should be the background color matching your design actually */
filter: chroma(#ffaabb); /* and this should match whatever value you put in background-color */
}

This may require more work on ie9 or later.

Macomatic
  • 113
  • 9
0

Just want to add (since I googled for this problem, and this question popped first) IE6 and other versions render PNG transparency very ugly. If you have PNG image that is alpha transparent (32bit) and want to show it over some complex background, you can never do this simply in IE. But you can display it correctly over a single colour background as long as you set that PNG images (or divs) CSS attribute background-color to be the same as the parents background-color.

So this will render black where image should be alpha transparent, and transparent where alpha byte is 0:

<div style="background-color: white;">    
    <div style="background-image: url(image.png);"/>    
</div>

And this will render correctly (note the background-color attribute in the inner div):

<div style="background-color: white;">    
    <div style="background-color: white; background-image: url(image.png);"/>    
</div>

Complex alternative to this which enables alpha image over a complex background is to use AlphaImageLoader to load up and render image of the certain opacity. This works until you want to change that opacity... Problem in detail and its solution (javascript) can be found HERE.

Cipi
  • 11,055
  • 9
  • 47
  • 60
0

My scenario:

  • I had a background image that had a 24bit alpha png that was set to an anchor link.
  • The anchor was being faded in on hover using Jquery.

eg.

a.button { background-image: url(this.png; }

I found that applying the mark-up provided by Dan Tello didn't work.

However, by placing a span within the anchor element, and setting the background-image to that element I was able to achieve a good result using Dan Tello's markup.

eg.

a.button span { background-image: url(this.png; }
codeinthehole
  • 8,876
  • 3
  • 25
  • 34
  • span's are not block level elements, how could this work unless you set display:block and height/width? – Brenden Feb 17 '12 at 19:41
  • @Brenden; if I remember rightly, I would have used 'display: block'. If an anchor wraps a div, the mark-up won't pass validation - hence the reason for using a span tag. – codeinthehole Feb 17 '12 at 21:39