CSS中用 opacity、visibility、display 属性将 元素隐藏 的 对比分析
说明
opacity 用来设置透明度
display 定义建立布局时元素生成的显示框类型
visibility 用来设置元素是否可见。
opacity、visibility、display 这三个属性分别取值 0、hidden、none 都能使元素在页面上看不见,但是他们在方方面面都还是有区别的。
是否占据页面空间
举个例子
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.yellow{
width:100px;
height:100px;
background:yellow;
}
.red{
width:100px;
height:100px;
background:red;
}
</style>
</head>
<body>
<div class="yellow"></div>
<div class="red"></div>
</body>
</html>
最开始的样子
黄色块div元素 使用 opacity:0;
时
黄色块div元素 使用 visibility:hidden;
时
黄色块div元素 使用 display:none;
时
可以看出,使用 opacity 和 visibility 属性时,元素还是会占据页面空间的,而使用 display 属性时,元素不占据页面空间。
对子元素的影响
如果子元素什么都不设置的话,都会受父元素的影响,和父元素的显示效果一样,我们就来举例看看,如果子元素设置的值 和 父元素设置的值不同会有什么效果。
例子 (opacity属性)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.yellow{
width:100px;
height:100px;
background:yellow;
opacity:0; /* 父元素的 opacity属性取值为0 */
}
.blue{
width:50px;
height:50px;
background:blue;
opacity:1; /* 子元素的 opacity属性取值为1 */
}
</style>
</head>
<body>
<div class="yellow">
<div class='blue'></div>
</div>
</body>
</html>
例子 (visibility属性)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.yellow{
width:100px;
height:100px;
background:yellow;
visibility:hidden; /* 父元素的 visibility属性取值为hidden */
}
.blue{
width:50px;
height:50px;
background:blue;
visibility:visible; /* 子元素的 visibility属性取值为visible */
}
</style>
</head>
<body>
<div class="yellow">
<div class='blue'></div>
</div>
</body>
</html>
例子 (display属性)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.yellow{
width:100px;
height:100px;
background:yellow;
display:none; /* 父元素的 display属性取值为none */
}
.blue{
width:50px;
height:50px;
background:blue;
display:block; /* 子元素的 display属性取值为block */
}
</style>
</head>
<body>
<div class="yellow">
<div class='blue'></div>
</div>
</body>
</html>
可以看出,使用 opacity 和 display 属性时,父元素对子元素的影响很明显,子元素设置的 opacity 和 display 属性是不起作用的,显示的效果和父元素一样,而使用 visibility 属性时,子元素如果设置为 visibility:visible;
并没有受父元素的影响,可以继续显示出来。
自身绑定的事件是否能继续触发
这里说的触发事件,是指用户人为的触发的事件,不包括使用 JavaScript 模拟触发的事件。
例子 (opacity属性)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.yellow{
width:100px;
height:100px;
background:yellow;
opacity:0;
}
</style>
</head>
<body>
<div class="yellow" onmouseenter="alert(0)"></div>
</body>
</html>
例子 (visibility属性)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.yellow{
width:100px;
height:100px;
background:yellow;
visibility:hidden;
}
</style>
</head>
<body>
<div class="yellow" onmouseenter="alert(0)"></div>
</body>
</html>
使用 display:none;
就不用举例子了,因为使用 display 属性的话,元素不仅看不见,而且也不占据页面空间,所有不会触发事件。
总的来说,使用 visibility 和 display 属性,自身的事件不会触发,而使用 opacity 属性,自身绑定的事件还是会触发的。
是否影响其他元素触发事件
例子(opacity属性)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.red{
width:400px;
height:40px;
background:red;
position:relative;
}
.yellow{
position:absolute;
top:0;
left:0;
width:200px;
height:300px;
background:yellow;
opacity:0;
}
.blue{
width:200px;
height:200px;
background:blue;
}
.red:hover .yellow{
opacity:1;
}
</style>
</head>
<body>
<div class='red'>
<div class='yellow'></div>
</div>
<p class='blue' onmouseenter=alert(0)></p>
</body>
</html>
黄色块div元素设置 opacity:0;
,通过定位,遮挡住了 蓝色的p元素,当鼠标移到蓝色p元素上时,并没有触发蓝色p元素的事件。
例子(visibility属性)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.red{
width:400px;
height:40px;
background:red;
position:relative;
}
.yellow{
position:absolute;
top:0;
left:0;
width:200px;
height:300px;
background:yellow;
visibility:hidden;
}
.blue{
width:200px;
height:200px;
background:blue;
}
.red:hover .yellow{
visibility:visible;
}
</style>
</head>
<body>
<div class='red'>
<div class='yellow'></div>
</div>
<p class='blue' onmouseenter=alert(0)></p>
</body>
</html>
黄色块div元素设置 visibility:hidden;
,通过定位,虽然遮挡住了 蓝色的p元素,但是当鼠标移到蓝色p元素上时,还是触发了蓝色p元素绑定的事件。
和上边一样,display 属性就不举例子了,因为他不会占据页面空间,也就不会遮挡其他元素,就不会影响其他元素触发事件了。
所以,visibility 和 display 属性是不会影响其他元素触发事件的,而 opacity 属性 如果遮挡住其他元素,其他的元素就不会触发事件了。
是否产生回流(reflow)
回流
当页面中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(也有人会把回流叫做是重布局或者重排)。
每个页面至少需要一次回流,就是在页面第一次加载的时候。
dispaly 属性会产生回流,而 opacity 和 visibility 属性不会产生回流。
是否产生重绘(repaint)
重绘
当页面中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的时候,比如background-color。则称为重绘。
dispaly 和 visibility 属性会产生重绘,而 opacity 属性不一定会产生重绘。
元素提升为合成层后,transform 和 opacity 不会触发 repaint,如果不是合成层,则其依然会触发 repaint。
在 Blink 和 WebKit 内核的浏览器中,对于应用了 transition 或者 animation 的 opacity 元素,浏览器会将渲染层提升为合成层。
也可以使用 translateZ(0) 或者 translate3d(0,0,0) 来人为地强制性地创建一个合成层。
举个例子
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="target">重绘 repaint</div>
<script>
var flag = false;
setInterval(function () {
flag = !flag;
target.style.opacity = flag ? 0 : 1;
},1000)
</script>
</body>
</html>
我们可以用 Chrome DevTools 的 Rendering 来看看,
先打开 Rendering
把第一个选项勾选,这个选项会 高亮显示需要重绘的区域。
看看效果
改改代码,增加上个 transition
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
div{
transition:1s;
}
</style>
</head>
<body>
<div id="target">重绘 repaint</div>
<script>
var flag = false;
setInterval(function () {
flag = !flag;
target.style.opacity = flag ? 0 : 1;
},1000)
</script>
</body>
</html>
再看看效果
加上 transition 后就没有 高亮显示了,这时候 opacity 不会触发重绘。
实际上透明度改变后,GPU 在绘画时只是简单的降低之前已经画好的纹理的 alpha 值来达到效果,并不需要整体的重绘。不过这个前提是这个被修改的 opacity 本身必须是一个图层,如果图层下还有其他节点,GPU 也会将他们透明化。
注意:回流必将引起重绘,而重绘不一定会引起回流。
是否支持transition
opacity 是支持 transition的,一般淡入淡出的效果就是这样实现的。
visibility 也是支持 transition 的。
visibility: 离散步骤,在0到1数字范围之内,0表示“隐藏”,1表示完全“显示”
visibility : hidden;
可以看成 visibility : 0;
visibility : visible;
可以看成 visibility : 1;
只要 visibility 的值大于0就是显示的,所以
visibility:visible 过渡到 visibility:hidden,看上去不是平滑的过渡,而是进行了一个延时。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.blue{
width:200px;
height:200px;
background:blue;
transition:1s;
visibility:visible;
}
.blue:hover{
visibility:hidden;
}
</style>
</head>
<body>
<div class='blue'></div>
</body>
</html>
而如果 visibility:hidden 过渡到 visibility:visible ,则是立即显示,没有延时。
注意
上面这个例子只能是从 visibility:visible 过渡到 visibility:hidden
,不能从 visibility:hidden 过渡到 visibility:visible
。
当元素是 visibility:hidden;
时,自身的事件不会触发,所以像上面这个例子中,直接在蓝色块div元素 上加 hover 事件,要去将自身的 visibility:hidden 过渡到 visibility:visible
是不会起作用的。
但是在其他元素上加事件,来将该元素的 visibility:hidden 过渡到 visibility:visible
是可以的,看例子。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.red{
width:200px;
height:200px;
background:red;
}
.blue{
width:200px;
height:200px;
background:blue;
transition:1s;
visibility:hidden;
}
.red:hover+.blue{
visibility:visible;
}
</style>
</head>
<body>
<div class='red'></div>
<div class='blue'></div>
</body>
</html>
display 不仅不支持transition,它还会使 transition 失效。举个例子看看
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.blue{
width:200px;
height:200px;
background:blue;
}
.yellow{
width:100px;
height:100px;
background:yellow;
opacity:0;
display:none;
transition:1s
}
.blue:hover .yellow{
opacity:1;
display:block;
}
</style>
</head>
<body>
<div class='blue'>
<div class='yellow'></div>
</div>
</body>
</html>
可以看出用了display,支持 transition 的 opacity 属性也没起作用。
这是因为display:none;
的元素,是不会渲染在页面上的,而 transition 要起作用,元素必须是已经渲染在页面上的元素,我们可以再来看个例子
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.blue{
width:200px;
height:200px;
background:blue;
}
.yellow{
width:100px;
height:100px;
background:yellow;
opacity:0;
transition:1s
}
</style>
</head>
<body>
<span>渲染到页面</span>
<div class='blue'></div>
<script>
var span = document.querySelector('span');
span.addEventListener('click',function(){
var yellowDiv = document.createElement('div');
yellowDiv.classList.add('yellow');
var blue = document.querySelector('.blue');
blue.appendChild(yellowDiv);
yellowDiv.style.opacity = '1';
})
</script>
</body>
</html>
给 span 元素绑定事件,点击它的时候,才会把黄色块div元素,渲染到DOM树上,然后改变黄色块div元素的 opacity 属性,opacity 是支持 transition 的,而在这段代码中,并没有起作用。
更详细的关于 transition 是否成功 的解读看这里
渲染树决定 transtion 能否成功
要想解决这个问题,我们可以这样做。
1、把 display 属性换成 visibility 属性
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.blue{
width:200px;
height:200px;
background:blue;
}
.yellow{
width:100px;
height:100px;
background:yellow;
opacity:0;
visibility:hidden;
transition:1s
}
.blue:hover .yellow{
opacity:1;
visibility:visible;
}
</style>
</head>
<body>
<div class='blue'>
<div class='yellow'></div>
</div>
</body>
</html>
2、如果必须要用 display 属性,我们可以加上定时器来解决这个问题
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.blue{
width:200px;
height:200px;
background:blue;
}
.yellow{
width:100px;
height:100px;
background:yellow;
display:none;
opacity:0;
transition:1s;
}
</style>
</head>
<body>
<div class='blue'>
<div class='yellow'></div>
</div>
<script>
var blue = document.querySelector('.blue');
blue.addEventListener('mouseenter',function(){
var yellowDiv = document.querySelector('.yellow');
yellowDiv.style.display = 'block';
setTimeout(function(){
yellowDiv.style.opacity = '1';
},0);
})
</script>
</body>
</html>
总结
CSS中用 opacity、visibility、display 属性将 元素隐藏 的 对比分析的更多相关文章
- CSS学习笔记05 display属性
HTML标记一般分为块标记和行内标记两种类型,它们也称块元素和行内元素. 块元素 每个块元素通常都会独自占据一整行或多整行,可以对其设置宽度.高度.对齐等属性,常用于网页布局和网页结构的搭建.并且块级 ...
- CSS学习笔记:display属性
目录 一.display属性概述 1. 块级元素和行内元素的区别 2.常见的块级元素和行内元素 3. display属性常见的属性值 二.测试display取各属性值的效果 1. 测试inline和b ...
- CSS传统布局之display属性+float属性+position属性
这三个属性是传统网页布局中经常用到的属性. 读这篇文章之前,希望你对css布局模型已经有了一定的了解.因为本文的三个属性是和css三个布局模型紧密联系在一起的.因此,如若你并不了解,我推荐你先看一下c ...
- jquery控制css的display属性(显示与隐藏)
jquery控制div的显示与隐藏,很方便的. 例如: $("#id").show()表示display:block, $("#id").hide()表示dis ...
- 转: 详解css中的display属性
在一般的CSS布局制作时候,我们常常会用到display对应值有block.none.inline这三个值.下面我们来分别来认识和学习什么时候用什么值.这里通过CSS display知识加实例讲解方法 ...
- CSS display 属性
实例 使段落生出行内框: p.inline { display:inline; } 所有主流浏览器都支持 display 属性. 注释:如果规定了 !DOCTYPE,则 Internet Explor ...
- 对CSS进行wxss思路学习,display属性。
先来概要一下学习思路: 本系列内容,将针对微信小程序中的WXSS学习,所以在学习CSS时每一个知识点都在小程序IDE中进行实践,达到最好的学习效果. 由于wxss与CSS有些许不同,在学习CSS过程中 ...
- (十二)学习CSS之display属性
参考:http://www.w3school.com.cn/cssref/pr_class_display.asp 浏览器支持 所有主流浏览器都支持 display 属性. 注释:如果规定了 !DOC ...
- 元素隐藏的方式之--hidden,display,visibility
<html lang="en"> <head> <meta charset="UTF-8"> <title>标签 ...
随机推荐
- Window7 系统下重新建立一个新分区
为了方便使用,准备在原来分区上再分割出一个分区,步骤如下 首先右击计算机,选择管理打开计算机管理窗口,选择磁盘管理,当前窗口右侧会出现当前计算机所有已存在的分区列表. 选择要进行分区的磁盘,右击选择压 ...
- LongAccumulator 源码分析
LongAccumulator LongAccumulator 能解决什么问题?什么时候使用 LongAccumulator? 1)LongAccumulator 的逻辑和 LongAdder 基本类 ...
- spring集成mongodb通过aop记录业务日志
1. 编辑 pom.xml 添加 maven 依赖 <!-- mongodb --> <dependency> <groupId>org.mongodb</g ...
- write()与writelines()
f = open('user','a+') f.write('abcde') #write只能写字符串 f.writelines(['444','rrrr','uuu']) #writeline ...
- Delphi MlSkin V1.1 发布啦! 它能让你的程序拥有像QQ一样多彩炫丽的外观!
http://bbs.csdn.net/topics/390740239 本帖最后由 u014161811 于 2014-03-24 09:46:40 编辑 QQ皮肤透明TEdit透明TMemo图片按 ...
- 21次C++作业
//第一题目 class A //A为基类 {public: void f1( ); int i; protected: void f2(); int j; private: int k; }; /* ...
- 实验报告3&学习总结
1.已知字符串:"this is a test of java".按要求执行以下操作: 统计该字符串中字母s出现的次数. 统计该字符串中子串"is"出现的次数. ...
- 两道CTF Web的题目
1.easyphp 1.1.题目描述 题目首先是一张不存在的图片 查看源码发现只有一句话 <img src="show.php?img=aGludC5qcGc=" width ...
- hdu-4185.loiol_skimming(简单二分匹配模型)
/************************************************************************* > File Name: hdu-4185. ...
- Vue.js 源码学习笔记
最近饶有兴致的又把最新版 Vue.js 的源码学习了一下,觉得真心不错,个人觉得 Vue.js 的代码非常之优雅而且精辟,作者本身可能无 (bu) 意 (xie) 提及这些.那么,就让我来吧:) 程序 ...