关于png、背景透明疑难杂症综合帖
前言
在web重构中,为了追求视觉效果,会经常使用标签背景透明、透明的png图片等,可惜ie6未死,所以经常会有这样那样的问题出现,下面我总结一下ie6下各种怪症和解决方法。
标签背景透明
常规方法
1、火狐、谷歌等现代浏览器使用 opacity 属性,ie9以下浏览器使用ie私有滤镜 filter:alpha(opacity=60) 实现
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>demo-标签背景透明</title> 6 <meta name="Keywords" content="" /> 7 <meta name="Description" content="" /> 8 <style type="text/css"> 9 *{ margin: 0; padding: 0;} 10 .wrapper{ margin: 100px 0px 0 100px;} 11 .demo{ width: 300px; height: 200px; float: left; margin-right: 20px; display: inline; background-color: #f00; } 12 .demo1{ opacity:0.5; filter:alpha(opacity:50);} 13 </style> 14 </head> 15 <body> 16 <div class="wrapper"> 17 <div class="demo"> 18 原始不透明 19 </div> 20 <div class="demo demo1"> 21 width: 300px; height: 100px; margin: 100px auto; background-color: #f00; opacity:0.5; filter:alpha(opacity:50); 22 </div> 23 </div> 24 </body> 25 </html>
效果如图:
问题
可以看到,红色背景变成百分之50的半透明,但是标签内容文字也被半透明了,这不是我们想要的。
解决
例如增加一个div,将透明效果加到这个空div上,通过定位,将其与内容重叠。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>demo-标签背景透明</title> 6 <meta name="Keywords" content="" /> 7 <meta name="Description" content="" /> 8 <style type="text/css"> 9 *{ margin: 0; padding: 0;} 10 .wrapper{ margin: 100px 0px 0 100px;} 11 .demo{ width: 300px; height: 200px; float: left; margin-right: 20px; display: inline; background-color: #f00; } 12 .demo1{ position: relative; background: none;} 13 .content{ position: relative; z-index: 1000;} 14 .tmpDiv{ position: absolute; z-index: 0; left: 0; top: 0; width: 300px; height: 200px; background-color: #f00; opacity:0.5; filter:alpha(opacity:50);} 15 </style> 16 </head> 17 <body> 18 <div class="wrapper"> 19 <div class="demo"> 20 原始不透明 21 </div> 22 <div class="demo demo1"> 23 <div class="content">增加一个空 div,通过定位,将其与内容重叠。</div> 24 <div class="tmpDiv"></div> 25 </div> 26 </div> 27 </body> 28 </html>
效果如下:
更好的方法
上面这种方法,需要增加一个空标签,改变了dom结构,又使用了定位,开销太大了,其实有更好的解决方法。
众所周知,css3增加了一个新的属性 RGBA(R,G,B,A), r/g/b/a,分别代表红色、绿色、蓝色和alpha透明度,a就是我们要用到的。用它产生的透明,不会对其内容产生影响。
比如背景50%透明的红色,background:rgba(255,0,0,0.5);
ie9以下是不支持rgba的,但ie有私有的渐变滤镜。
.demo2{ filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#7FFF0000', EndColorStr='#7FFF0000';}
看这两个参数:StartColorStr和EndColorStr,他们的值第二三位表示7F透明度0.5,后6位ff0000表示红色。
由于ie9既支持rgba又支持ie滤镜,所以会造成透明值叠加,需要hack一下:
:root .demo2{filter:none;}/*for IE9*/
综合起来css如下:
.demo2{ background-color: rgba(255,0,0,0.5); filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#7FFF0000', EndColorStr='#7FFF0000'); }
:root .demo2{ filter:none;}
完整代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>demo-标签背景透明</title> <meta name="Keywords" content="" /> <meta name="Description" content="" /> <style type="text/css"> *{ margin: 0; padding: 0;} .wrapper{ margin: 100px 0px 0 100px;} .demo{ width: 300px; height: 200px; float: left; margin-right: 20px; display: inline; background-color: #f00; } .demo1{ position: relative; background: none;} .content{ position: relative; z-index: 1000;} .tmpDiv{ position: absolute; z-index: 0; left: 0; top: 0; width: 300px; height: 200px; background-color: #f00; opacity:0.5; filter:alpha(opacity:50);} .demo2{ background: none; background-color: rgba(255,0,0,0.5); filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#7FFF0000', EndColorStr='#7FFF0000'); } :root .demo2{ filter:none;} </style> </head> <body> <div class="wrapper"> <div class="demo"> 原始不透明 </div> <div class="demo demo1"> <div class="content">增加一个空 div,通过定位,将其与内容重叠。</div> <div class="tmpDiv"></div> </div> <div class="demo demo2"> demo2 采用 rgba </div> </div> </body> </html>
效果图
png图片透明
工作中,经常遇到一些带有半透明、阴影模糊的图片,这时就需要将图片导出为png格式了。PS中,png有两种格式,png-8和png-24。
问题
png8只有256位索引色,但它有一个alpha透明通道,一般用来保存各种小图标,体积小巧,比gif质量好很多;如果图片带有较多的模糊,透明渐 变,png8的效果就很差了,这时需要保存为png24,但是在ie6这个不争气的浏览器下,png24背景不会透明,反而带有一个灰色的背景。
解决方法
在兼顾图片质量的情况下,能用png8就用png8,png24的话,如果可以连背景切就把背景也放进去,逼不得已使用png24,ie6解决方案:
- ie私有alpha滤镜:.bg{ background:url(../images/top_19.png) no-repeat; _background:none; _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale, src='images/top_19.png');} 这个方法确缺点很明显,用处很局限,背景图片,而且不能再用css-sprite了,background被none了,没有background-position,还要注意src的路径,是相对于html文件的。
- 各种插件,js、htc等,推荐使用DD_belatedPNG,它不仅对背景图片有效,对img也有效,用法:引入js,在需要处理的图片上加上class,例如png_bg;
<!--[if IE 6]> <script type="text/javascript" src="js/DD_belatedPNG_0.0.8a-min.js"></script> <script type="text/javascript">DD_belatedPNG.fix('.png_bg');</script> <![endif]-->
缺点
dd_belatedPNG也不是完美的解决方法,有时还是会出现各种小问题的,png图片太多,加载太慢,加载不完整,只显示图片的一小部分,或者在某些交互事件中,比如鼠标经过,切换图片,切换出来的图片没有被fix,等等。
结语
关于png透明图片的处理,还是那句话,能用png8就尽量用png8,或者连背景一起切,各种插件,不是有小问题就是有性能问题。我们只能期望ie6早点“归西”吧。
posted on 2012-04-29 13:37 leecan_zeng 阅读(1169) 评论(3) 编辑 收藏 举报