【BUG】IE滤镜处理PNG图片有严重的BUG!
今天突然发现一个很严重的问题:在IE6,7,8下带有Alpha通道的png图片设置滤镜,图片的半透明像素全都变成了黑点!
虽说IE的滤镜不是标准的东西,不推荐使用,但是对于处理透明度这类问题还是经常会用到。下面就讨论最常用的一个滤镜:filter:alpha()。
说白了,我们就是给一个带半透明像素点的PNG-24图片设置透明滤镜。这在其他浏览器上都是没有任何问题的,唯独IE!
这类效果并非罕见。现在PNG格式使用越来越多,他不仅可以带有alpha通道,而且压缩率也比gif高。如果你在做一个图片淡入浅出的效果,图片里正好带有半透明的点,那你就会碰到这个问题。
首先我们选择一幅带有半透明点的png图片,注意下面的半透明部分:
页面的背景色是#660,观察在IE6/7/8下的表现。因为ie6不支持半透明点,所以就变成了灰色,这个大家都知道。半透明部分融入了背景色,可以很明显看出来。
然后我们给img元素添加alpha滤镜,这下问题立即暴露出来了:原先下面渐变的圆圈现在变成实心的了,半透明的点都被替换成了黑色!经测试,不仅是alpha滤镜,所有的IE滤镜都会丢失png的半透明像素。
在反复试验后发现,给img添加一个背景色,那些半透明的点又正常了:
<img src="alpha.png" style="filter:alpha(opacity=20); background:#FFF" />
为了不让白色显示出来,将#FFF改为transparent,但这样一来,半透明像素又罢工了:(
不过对于本例页面背景是纯色的情况下,设置和页面一样的背景色倒是行得通!
<img src="alpha.png" style="filter:alpha(opacity=20); background:#660" />
但是绝大多数情况下图片后面都是有复杂的背景的,所以这样还是行不通。我们尝试在img外嵌套div,把滤镜设置在div上面:
<style> body {background: #660} div { position:absolute; filter: alpha(opacity=20); width: 256px; height: 256px; } img { position:absolute; } </style> <div> <img src="alpha.png" /> </div>
这次在IE8里出现了一个很诡异的现象:img元素没有被应用上滤镜!原因就是其设置了position:absolute。如果去掉这句,就和IE7表现一样。由此可见ie8还有这样一个bug:滤镜不会应用到绝对定位的子元素上!不过在加了<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />兼容模式就没问题了。
经过一番测试,div嵌套img仍然行不通。我们不妨用div嵌套div,而且不用background加载图片。如果你记性好的话,应该知道ie有个AlphaImageLoader的滤镜,我们试着用它加载png:
<style> body{background: #660} .out { filter: alpha(opacity=20); width: 256px; height: 256px; } .in { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='alpha.png'); width: 256px; height: 256px; } </style> <div class="out"> <div class="in"></div> </div>
这回可总算对了!不仅在ie7,ie8下正确显示,连咱们的老祖宗ie6都通了。大功告成!
所以,以后制作PNG图片淡入浅出的效果时,IE下应使用AlphaImageLoader来载入图片,代替背景图,以避免半透明像素的丢失:
<style>
body{background: #660}
.out
{
width: 256px;
height: 256px;
filter: alpha(opacity=20);
opacity: 0.2;
}
.in
{
background: url(alpha.png);
*background: none;
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='alpha.png');
width: 256px;
height: 256px;
}
</style>
<div class="out">
<div class="in"></div>
</div>