zoukankan      html  css  js  c++  java
  • 关于opacity透明度子元素继承现象的若干研究以及hack方法

    【感想】信息时代的信息是有时效性的,今天是确确实实感受到了。互联网资料虽然丰富,但是质量不一,还有大量的跟风雷同,很多人都是随手拷贝过来,根本没有实践。以前端为例,这两年浏览器的迅猛发展,造成很多原有知识的失效。但是网上还是大量充斥了以前失效的解决方案。我觉得,我们应本着实践精神,对任何问题的解决方案进行实际测试。须知:纸上得来终觉浅,绝知此事要躬行。

    今天遇到一个关于透明度的问题。

    大家都知道在css3中增加的新属性opacity——不透明度的设定。

    使用了opacity的元素,它的不透明度会被子元素继承。例如:1_demo.html

    代码如下:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-cn">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
        <title></title>
        <style type="text/css">
        body{ background-color: #000; }
        .a{ width: 200px; height: 150px; background-color: #37a7d7; color: #fff; }
        .opacity{ filter:alpha(opacity=50); /*for IE*/opacity: 0.5;/*非IE*/ }
        </style>
    </head>
    <body>
        <div class="a">我是b-DIV</div>
        <div class="a opacity">我是b-DIV</div>
    </body>
    </html>

    效果如下:

    image

    可以看出,不光b-DIV本身透明度改变了,他的子元素的透明度也跟着改变了。

    有时候我们不希望子元素的透明度改变,例如上面的例子,我们不希望里面的字也变得透明。下面我们做几个实验试试。

    一、

    网上流传很广的一个方法,是给子元素在给包裹起来,然后设置position为relative或者absolute

    例如,我们更改上面例子的代码,2_demo.html

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-cn">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
        <title></title>
        <style type="text/css">
        body{ background-color: #000; }
        .a{ width: 200px; height: 150px; background-color: #37a7d7; color: #fff; }
        .opacity{ filter:alpha(opacity=50); /*for IE*/opacity: 0.5;/*非IE*/ }
        </style>
    </head>
    <body>
        <div class="a">
            <div>我是b-DIV</div>
        </div>
        <div class="a opacity">
            <div style="position:relative">我是b-DIV</div><!-- 我是新增代码 -->
        </div>
    </body>
    </html>

    firefox31下:

    image

    chrome35下:

    image

    IE9-11下:

    image

    但是在IE7、8下竟然可以:

    无标题

    老办法还真是只能对付“老浏览器”…….

    二、

    看来在firefox、chrome和IE9/10/11 下,利用position把子元素脱出文档流这种方法应该是无解了。

    那我们换个思路,直接给子元素定义opacity:1行不行。

    <div style="position:relative;opacity: 1">我是b-DIV</div>

    例子:3_demo.html

    image

    其实是这样的,如果父元素定义了opacity,那么子元素在定义一个opacity,那么子元素的效果其实是两者的乘积…

    例如,父元素的opacity:0.5,子元素opacity:0.2,那么子元素实际的opacity=0.5x0.2=0.1

    这个大家可以自己尝试下就知道了。

    设置了opacity的父元素,此属性一定会被子元素继承。

    三、

    第三种方法:使用css3的另一个属性:background-color:rgba();

    以上面的背景色 #37a7d7为例,其rgb写法为:rgb(55,167,215),两者可以等价交换。

    在css3中的rgba(),rgba(55,167,215,0.5),其中第四项0.5即为不透明度。

    例子:4_demo.html

    image

    聪明的你一定马上想到那么

    background-color:rgba(55,167,215,0.5);

    等价于

    background-color:rgb(55,167,215);opacity:0.5;

    是,也不完全是。因为对于使用rgba设置的不透明度,子元素是不会继承的。

    但是,IE7、8是不支持rgba()…..

    四、

    通过上面这些方法,我们可以看出来,子元素是必须继承父元素的opacity。那我们再换个思路,不让它成为子元素呢?例子:5_demo.html

    代码:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-cn">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
        <title></title>
        <style type="text/css">
        body{
        background-color: #000;margin: 0;padding: 0;
    }
        .noOpacity{
        width: 300px;
        height: 250px;
        background-color: #37a7d7;
        color: #fff;
    }
    /*上面的是背景对比,以下是方法*/
        .container {
        width: 300px;
        height: 250px;
        color: #fff;
        position:relative;
    }
       .content {
        position:relative;
        z-index:5;
        width: 100%;
        height: 100%;
        overflow: hidden;
    }
       .background {
        background-color: #37a7d7;
        position:absolute;
        top:0px;
        left:0px;
        width:100%;
        height:100%;
        z-index:1;
        /*兼容IE7、8 */
           -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
        filter: alpha(opacity=50);
        opacity:.5;
    }
        </style>
    </head>
    <body>
        <div class="noOpacity">我是用来作对比的</div>
        <div class="container">
            <div class="content">
                <p>我是class为content的DIV</p>
                <p>我的背景是class为background的背景</p>
                <p>通过相对定位和绝对定位,我把class为background的DIV移动到了我的位置。</p>
                <p>同时通过我的较大的z-index浮在了它的上面。 :)</p>
                <p style="text-align:right">——刘龙(liulo)</p>
            </div>
            <div class="background"></div>
        </div>
    </body>
    </html>

    效果:

    22222222222

    perfect!!完美兼容FF31、chrome35、以及IE7-11。

    总结

    经过 以上讨论,我们发现纯代码方面除了方法四,其他的都或多或少存在兼容性问题,当然你也可以通过判断浏览器使用javascript改变DOM,这样一来未免得不偿失。

    在需要兼容IE7、8的情况下,除了方法四,还可以用传统的方法——gif/png图片……

    ps:以上方法在IE6中均不可实现。

    建议阅读stackoverflow上的相关讨论:http://stackoverflow.com/questions/806000/transparent-background-but-not-the-content-text-images-inside-it-in-css-on#

  • 相关阅读:
    pat 甲级 1065. A+B and C (64bit) (20)
    pat 甲级 1064. Complete Binary Search Tree (30)
    pat 甲级 1010. Radix (25)
    pat 甲级 1009. Product of Polynomials (25)
    pat 甲级 1056. Mice and Rice (25)
    pat 甲级 1078. Hashing (25)
    pat 甲级 1080. Graduate Admission (30)
    pat 甲级 团体天梯 L3-004. 肿瘤诊断
    pat 甲级 1099. Build A Binary Search Tree (30)
    Codeforce 672B. Different is Good
  • 原文地址:https://www.cnblogs.com/liu-l/p/3890861.html
Copyright © 2011-2022 走看看