IE6以下浏览器这里不考虑。
前言:IE6不支持png背景透明或半透明。其解决方法有IE滤镜,纯粹的JavaScript,以及jQuery等,正所谓事非经过不知难,让png图片在IE6下背景透明显示只是第一步,如果对这些png图片做进一步的操作,往往会出现各类莫名的问题。而本篇文章讲详尽阐述png背景透明会出现哪些问题,一些自己的经验之谈和一些相关的拓展。内容较多,有一定的深度和广度,希望对大家有帮助。
目录:
一、可解决的方法
1. css滤镜
2. 老JavaScript方法
3. jQuery实现
4. flash实现
二、产生的问题
1. 响应单击事件
2. 图片大小控制
3. 背景图片的定位
三、相应的解决方法
1. 响应单击事件
2. 图片大小控制
3. 背景图片的定位
四、相关延伸的问题
1. png8与png24的半透明显示
2. IE7的半透明滤镜与png背景透明
一、可解决的方法
1. IE css 滤镜
IE css滤镜中有一个使png背景透明的滤镜,JavaScript方法也是应用的这个滤镜实现png背景透明的。
写法:filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’../image/png_test.png’);
用法示例:
.png{background:url(../image/png_test.png);}
* html .png {background:none; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’../image/png_test.png’);}
非IE6浏览器使用正常的background定位,IE6去除背景图片,应用png透明滤镜。
如果您的浏览器或内核为IE6,强烈建议点击这里进入demo实例页面
2.传统的JavaScript
使用传统的JavaScript方法,页面只要链接一个小巧的JavaScript文件就可以。例如,您可以在页面上添加如下代码:
<script src=”http://www.zhangxinxu.com/study/js/png.js” type=”text/javascript”></script>
这个JavaScript文件是我之前一直使用的使png背景透明的JavaScript文件,它可以让页面上所有的含有透明背景的png图片透明显示,支持background-image的png图片透明,但是不支持background-position定位;另外也不支持type类型为image的input框的png图片透明。
如果您是IE6或内核是IE6的浏览器,强烈建议点击这里查看demo实例页面
在这个页面,您可以清晰的看出此JavaScript的应用范围以及局限性。
3.jQuery png背景透明插件
相对于前面的方法,jQuery的IE6下png透明插件相对要强大些。
此插件js下载:jquery.pngFix.pack.js
使用的时候还要链接jQuery文件。
此js的强大之处在于不仅支持IE6下img标签的png背景透明,background-image的背景透明,还支持image类型的input的png背景透明那个,而且实现的精确控制,即您可以让页面上任意一张png图片背景透明而其他不受影响。
不管您是什么浏览器,强烈建议您点击这里进入精彩的demo实例页面吧。
您可以在这个页面上感受到此png 背景透明插件的强大。
4.使用flash装载png图片
使用flash装载png的原理是:flash对png的透明背景支持非常好,只要用户安装了flash插件,通过flash显示的png图片的背景必定是透明的。
实现的方法有两类,一种适合对flash不太熟的,就是直接将图片嵌入到flash中,方法如下:打开flash软件->设置舞台大小->将png图片拖到舞台(或导入到舞台)->导出flash->将swf插入在页面中->完毕;但是这种方法维护不讨方便,如果要更换图片,还要动flash源文件。另外一种就是与页面交互,从页面获取图片路径,最简单的方法之一就是通过FlashVars传参,再在flash中写上极短代码就可以了。
如果您感兴趣,建议您狠狠地点击这里进入demo实例页面参观参观。
页面上显示了flash获取页面参数的ActionScript代码,ActionScript 3.0代码,需要至少flash cs3版本的flash软件,直接写在第一帧上就可以了,另外设置舞台大小与图片一样大。
二、产生的问题
1.无法响应单击事件
这个问题在各个解决方法中都是存在的(即使是flash封装png的方法,其本身也不能响应click事件,只能背景透明情况下响应onmousedown事件),不是指本身无法响应单击事件,而是其内部的标签无法响应。举个简单的例子吧,一个div标签,里面有个a标签,a标签有个链接指向或有个js响应事件,而这个div标签有个png透明背景的图片,且在IE6下经过透明处理,那么这个a标签就是聋子的耳朵——摆设,只能看不能用。多说不宜,眼见为实,如果您的浏览器是IE6或内核为IE6请狠狠地点击这里,去感受下我所说的单击不响应是怎么个不响应法吧。如果您现在使用的是Firefox,chrome或是opera,Safari,但是您有该死的IE6浏览器,建议您委曲求全,也进来看看。
2.图片大小控制受到限制
这个问题在css png透明滤镜和老式的JavaScript方法中会遇到。问题简述如下:咳咳,一个img标签的src路径指向的是个含透明背景或半透明的png图片(例如:<img src=”xx.png” />),并且在IE6下,此图片受css滤镜或老式的JavaScript png透明处理,那么对该图片进行的任何大小限制拉伸都是瞎子点灯——白费蜡。再具体点说吧,假设我们这里的xx.png原始大小128像素*128像素,您使用css,img{width:256px; height:256px;}或是直接<img src=”xx.png” alt=”" width=”256″ height=”256″ />再或者是用上style<img style=”width: 256px; height: 256px;” src=”xx.png” alt=”" />要将他拉伸到256像素*256像素,您会发现有条比蜀道更难走的路——这张图片还是以其原始的大小显示,只是占据的空间变了。
上图为demo实例页面的小小截图,如果您是IE6浏览器,您可以狠狠地点击这里去看个清楚看个究竟。
3.无法对背景图片进行background-position定位
有个名词叫做css sprite。貌似是说很多背景图片集中到一张大图上,通过background-position定位,用到哪张图片就显示那部分区域,这好处大大的多,使用流行的很啊,优化大小,减小服务器压力,好处很多,里面颇有学问,但不是本文重点,不偏题。这个css sprite背景定位技巧在web2.0中可谓呼风唤雨,如鱼得水,但是遇到IE6浏览器,有时候他也只能哭了。如果背景图片是个含有透明背景的png图片,同时应用了IE6下背景透明显示处理的话,则该背景图片对background-position完全免疫。随便上面那个demo实例页面,保存下来,给这些background-image为png的图片再添加个background-position试试(比如background-position:-100px -100px;)您会发现不管用。如果您不想麻烦,直接狠狠地点击这里去看看吧。ps:要是IE6浏览器,不然没有效果的哦!
三、问题响应的解决方法
1.无法响应单击事件
要解决内部标签无法响应单击事件的问题,关键要把内部标签拿到外部,使用其他方法进行覆盖定位;或是不拿出来,使用另外的一个透明层或是透明图片进行定位与覆盖。最关键了一个词:覆盖;最难点:定位。说到覆盖性质的定位,无非两类,一是相对或绝对定位,二是margin负值定位。由于IE6下,父标签是position:relative;或是position:absolute属性时,里面的绝对定位层有时候会莫名消失,所以自己偏好于margin负值定位以及position:relative的负值定位。在此问题的demo实例页面最后一栏给了一个解决方法,margin负值定位解决的。方法很多,也很自由,就是覆盖,定位。您有兴趣可以试试点击这里去看看如何进行定位,如果解决此单击不响应问题的。
2.图片大小控制受到限制
这个问题的解决,说出来您不要笑我,就是去使用强大的jQuery png透明插件吧。这个插件不仅可以让指定的png透明,还支持image类型的input的png图片背景透明,更加重要的是其支持png图片的任意拉伸。
如果您是IE6浏览器,建议您狠狠地点击这里去看看图片美妙的拉伸控制,如果您目前使用的不是IE6浏览器,但是有,也建议您去看看。
3.无法对背景图片进行background-position定位
无法对背景图片进行background-position定位,那就拿到页面上进行定位就好了。使用img标签,src链接此背景大图,或是用span标签,其高宽就是整个大背景图的高宽,背景图片就是大背景图,在页面上对img或span这类标签进行定位,即可实现您想通过background-position实现的效果。
两大方法,margin定位与position定位。
这里需要分情况叙述。
首先,如果您直接使用的是css 滤镜或是传统的png透明JavaScript的话,这里的定位就是纯粹的margin定位或是absolute定位。这里概念说得比较含糊,实例说明吧。例如,我们将使用下面这张png按钮图片作为实例素材进行说明。
a.如果您使用的是css png透明滤镜,则需要将此png图片写在背景里,否则滤镜不起作用。写法如下:<img src=”http://www.zhangxinxu.com/study/image/pixel.gif” width=”640″ height=”80″ style=”background-image:url(/uploads/allimg/100312/0R45360U-2.png);” />(说明:这里的background-image要写在css里面,这里是为了方便说明才用style表示的)然后您所要做的就是对这个img标签进行margin定位或absolute定位。
例如,我这样写,<div style=”width:160px; height:40px; overflow:hidden;”><img src=”http://www.zhangxinxu.com/study/image/pixel.gif” width=”640″ height=”80″ style=”background-image:url(/uploads/allimg/100312/0R45360U-2.png); margin:-40px 0 0;” /></div>所显示的结果就是“首页”这个按钮鼠标经过的状态。通过margin控制图片的位置,由于父标签高宽以设定且溢出隐藏,所以就可以通过对图片的定位实现类似于background-position控制的效果。absolute绝对定位与margin定位其实是一样的,都是定位,应用的css属性不同而已。
b.如果您使用的是传统的JavaScript使得png透明,那么写法可以自由些。<img src=”/uploads/allimg/100312/0R45360U-2.png” />的写法也是可以的,其定位与上面是一样的,直接通过设定class用css控制即可,一般不会出现莫名的错误的。
c.如果您使用的是jQuery png透明插件,则问题似乎不那么简单的。原版的jQuery png透明插件使用页面上定位解决background-position不起作用的问题是由局限性的。例如出现overflow:hidden失效的问题,img标签不受控制的问题,无法使用绝对定位的问题。我对其插件代码简单分析了下,找到上述问题的原因,并对原来的JavaScript代码做了些修改,使其支持页面上的类似background-position的定位效果。所以建议您下载修改后的png插件js。
另外,这里img标签失效是由于此插件处理透明的原理是,将原来的img标签隐藏,用一个span标签获取img标签的相关样式属性,将src链接的png图片以background-image的形式表示,并应用png透明滤镜。也就是说,代码执行的结果是将img标签换成span标签。所以如果您通过img标签控制图片的位置大小或是其他什么属性都是徒劳的。解决方法是用id或class进行控制,您给img标签赋一个class,例如”png_pos”,则插件执行后,这个class会转移到span标签上,所以对”png_pos”这个class设置的样式不会丢失,依旧在页面上表现出来,而且不会出现兼容性的问题。
下面这张图显示的就是页面定位后的效果图,支持hover事件,鼠标经过导航按钮按钮背景变化的效果,乍看去像是background-position定位的效果,实际上是在页面上使用margin定位的效果。
针对jQuery插件下png大图在页面上定位的问题,我特地写了一个演示页面,并提供源文件的打包下载。如果您手头上的就是IE6浏览器或您有IE6或以IE6为内核的浏览器,建议您狠狠地点击这里,里面有完整的代码示例说明,相信可能会对上面我不逃清楚的措辞有进一步的了解。
四、相关延伸的问题
1.png8与png24的透明显示
说了这么多IE6不支持png背景透明指的是png24格式保存的含有透明背景的图片,而以png8格式存储的png图片的全透明背景是支持的。一个支持而另外一个不支持的原因在于:png24的透明背景是Alpha透明背景,而png8格式的全透明背景是索引透明背景与gif的透明背景是同一个类型。
如下显示:
如果您使用的正是IE6浏览器,狠狠地点击这里进入demo实例页面
我曾经遇到过png图片的半透明层直接被css png透明滤镜当作完全透明层处理掉的情况。但是今天我反复尝试都没有出现这个情况,我想可能当时的png图片是用fireworks制作,保存的时候将图层分层信息也保存进去了。既然,没有再次出现这样的问题,自己也不宜多说,妄下定论。
所说IE6支持png8的背景透明,但是最终的图片效果跟gif的其实差别不太,都存在一个同样的问题,锯齿。就像上面这张图,所说png8格式的图片长得貌似还不错,水灵水灵的。只要是正好是个白色背景,而png默认也是白色锯齿的,一重合,正好就看上去不错了。可以要是是个深色背景,那就是白骨精遇见孙悟空——原形毕露啊。
有关锯齿的问题,我会单独写篇文章,这里先简单说个处理方法,例如上面的图片,背景色为#666666灰色时,png白色锯齿显露,解决方法是在photoshop保存图片的时候,将杂边的颜色设为跟背景色一致就行了,例如这里杂边颜色就设为#666666,
然后保存即可。
2. IE7的alpha半透明滤镜与png背景透明
IE7 alpha半透明滤镜会影响其png24 Alpha透明通道的正常显示。下图为demo实例页面效果截图:
图中可以看到本应透明显示的部分现在确是黑色的一团,怎一个“丑”字了得。
如果您有IE7浏览器,建议您将这个地址http://www.zhangxinxu.com/study/200908/ie7-filter-opacity-png.html放在IE7浏览器下看看,会有更加直观的体验与认识。
五、小结
IE6注定要退出历史舞台,但是目前国内的状况来看,比如网吧,都是IE6浏览器;我的一些刚接触电脑不久的亲戚也都是使用的IE6浏览器。IE8的出现蚕食的只是IE7的比重,对IE6对没有什么大的影响,所以这个退出的时间还真不好说,至少目前一段时间还是很有比重的,因此IE6下的些问题不得不拿出来说说,png透明的问题是非常典型的一个问题。这里我也只是将自己碰到的问题整理总结了一下,有些地方可能说得比较含糊,有些地方可能有遗漏,还有些则是不想展开的太多,乱了主线。不管怎样,算是博客的第一篇技术类的文章吧,断断续续也写了还几天,希望这些糟糕的文字和略显业余的实例页面能对大家有帮助。至少在写的过程中我是学到了不少的。共同进步吧!
原创文章,转载请注明:转自张鑫旭-鑫空间-鑫生活 [http://www.zhangxinxu.com]