关于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>
效果如下:

可以看出,不光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下:

chrome35下:

IE9-11下:

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

老办法还真是只能对付“老浏览器”…….
二、
看来在firefox、chrome和IE9/10/11 下,利用position把子元素脱出文档流这种方法应该是无解了。
那我们换个思路,直接给子元素定义opacity:1行不行。
<div style="position:relative;opacity: 1">我是b-DIV</div>
例子:3_demo.html

其实是这样的,如果父元素定义了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

聪明的你一定马上想到那么
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>
效果:

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#
关于opacity透明度子元素继承现象的若干研究以及hack方法的更多相关文章
- Javascript禁止子元素继承父元素的事件
3种方法1.在父元素事件的function中加if(event.target==this){ }2.子元素事件function最后加event.stopPropgation():// 阻止事件冒泡3. ...
- jquery如何阻止子元素继承父元素的事件(又称事件冒泡)
非常简单,子元素上添加如下代码即可 $('a').click(function(e){ e.stopPropagation(); }); 老版本为event,现在用e就行
- jQuery如何阻止子元素继承父元素事件?
<a> <b></b> </a> $("a").click(...); 这种绑定的话,b也会响应一次事件,如何只对a元素绑定事件,而 ...
- javascript阻止子元素继承父元素事件
$('.box').on('click', function (e) { if(e.target == this) { console.log(e.target) } })
- css父元素透明度(opacity)对子元素的影响
首先子元素会继承父元素的透明度: 设置父元素opacity:0.5,子元素不设置opacity,子元素会受到父元素opacity的影响,也会有0.5的透明度. 其次子元素的透明度是基于父元素的透明度计 ...
- CSS中如何设置父元素透明度不影响子元素透明度
原因分析: 使用css的opcity属性改变某个元素的透明度,但是其元素下的子元素的透明度也会被改变,即便重定义也没有用,不过有个方法可以实现,大家可以看看. 可以使用一张透明的图片做背景可以达成效果 ...
- Javascript事件模型(二):Javascript事件的父元素和子元素
DOM事件标准定义了两种事件流,分别是捕获和冒泡.默认情况下,事件使用冒泡事件流,不使用捕获事件流.你可以指定使用捕获事件流,方法是在注册事件时传入useCapture参数,将这个参数设为true. ...
- js 下获取子元素的方法
笔记核心: firstElementChild只会获取元素节点对象,从名称就可以看出来,firstChild则可以获取文本节点对象(当然也可以获取元素节点对象),比如空格和换行都被当做文本节点. js ...
- 一个样例看清楚JQuery子元素选择器children()和find()的差别
近期在我们的hybrid app项目开发中定位出了一个问题.通过这个问题了解下JQuery选择器find()和children()的差别.问题是这种:我们的混合app是一个单页面应用(main.htm ...
随机推荐
- Linux 系统常用命令汇总(二) vi 文本编辑
文本编辑 vi 命令 作用 +文件名 编辑文本文件,若文件不存在同时创建该文件 Ctrl+f 向后翻一页 Ctrl+b 向前翻一页 Ctrl+d 向后翻半页 Ctrl+u 向前翻半页 + 光标移动到下 ...
- ZBrush中的SubTool工具该怎样使用
今天的ZBrush教程中将为大家引入一个新的工具SubTool,使用SubTool您可以添加PolyMesh至当前编辑的模型中,它的出现改变了过去ZBrush不能同时编辑多个模型的弊端. 查看详细的视 ...
- 2014 Super Training #4 B Problem Arrangement --状压DP
原题:ZOJ 3777 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3777 题意:给每个题目安排在每个位置的value ...
- Unity3D面试题汇总
1.请描述游戏动画有哪几种,以及其原理. 2.alpha blend 工作原理 3.写光照计算中的diffuse的计算公式 4.lod是什么,优缺点是什么 5.两种阴影判断的方法工作原理 6.MipM ...
- tomcat配置jenkins遇到的问题
在执行jenkinks时,遇到以下错误: 原因:未在tomcat/conf中的tomcat-users.xml中配置用户 解决方法:在tomcat/conf/tomcat-users.xml中添加以下 ...
- Visio使用遇到的问题
1.UML Background Add-on --------------------------- 此 UML 形状所在的绘图页不是 UML 模型图的一部分. 该形状设计用于利用 UML 模型图模 ...
- java 20 - 4 IO流概述和一个简单例子解析
IO流的分类: 流向: 输入流 读取数据 输出流 写出数据 数据类型: 字节流 字节输入流 读取数据 InputStream 字节输出流 写出数据 OutputStream 字符流 字符 ...
- Windows 2008 R2 配置 DNS 实现二级域名
本文内容 域名解析 准备工作 安装 DNS 服务器 建立 DNS 区域 建立主机头 服务器网络设置 测试二级域名 IIS 建立 Web 站点 其他 DNS 服务 域名解析 域名解析,是域名到 IP 地 ...
- esc设置多站点 域名解析
你的域名是:a.com IP: 1.1.1.1 一 设置域名解析: 1.a.com 解析到 1.1.1.1 2.a.com 解析到 2.2.2.2 LOOP 二 到服务器上: 在1站点设置主机 ...
- project和task
projects和tasks是Gradle中最重要的两个概念 任何一个Gradle构建狗屎一个或多个projects的组成.每个project包括许多可构建组成部分 什么是 project ? 一个j ...