關於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#


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM