Can's Blog

关注前端,记录,分享

导航

关于png、背景透明疑难杂症综合帖

前言

在web重构中,为了追求视觉效果,会经常使用标签背景透明、透明的png图片等,可惜ie6未死,所以经常会有这样那样的问题出现,下面我总结一下ie6下各种怪症和解决方法。

标签背景透明

常规方法

1、火狐、谷歌等现代浏览器使用 opacity 属性,ie9以下浏览器使用ie私有滤镜 filter:alpha(opacity=60) 实现

View Code
 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上,通过定位,将其与内容重叠。

View Code
 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;}

完整代码

View Code
<!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编辑  收藏  举报