CSS display | opacity | visibility的区别;回流与重绘

元素不可见的三种方法

opacity=0

opacity用来设置元素的透明度。
当该值为0时,该元素变透明,但是不会改变页面布局。
并且若此元素绑定了事件,点击该元素所占区域时,响应事件同样会被触发。

visibility=hidden

visibility用来设置元素的可见性。
当该值为hidden时,该元素变为不可见,但是不会改变页面布局。
对用户不可见后,点击相应的区域也无法触发绑定的事件

display=none

display定义建立布局时元素生成的显示框类型。
当该值为none时,该元素不再展示,会改变页面布局
点击相应的区域也无法触发绑定的事件

opacity : 0visibility : hiddendisplay : none
是否占据页面空间
对子元素的影响覆盖子元素 opacity : 1不覆盖子元素 visibility : visible覆盖子元素 display : none
监听的事件是否触发
被遮罩元素的监听事件是否触发(使用绝对定位覆盖)

回流与重绘

回流 reflow

若页面中某些元素的大小,位置,可见性等属性改变造成页面的布局需要重新构建时,产生回流。
回流又名重布局重排
每个页面在第一次加载时也会回流。

重绘 repaint

当页面的元素的属性更新,造成元素的外观风格改变时(页面布局不改变),产生重绘。

回流必将引起重绘,而重绘不一定会引起回流

查看重绘区域

Chrome => DevTools => Rendering => Paint flashing
需要重绘的区域将被高亮

opacityvisibilitydisplay
回流
重绘不一定
元素自身+transition&元素自身监听事件=>产生渐隐渐显效果
元素自身+transition&其他元素监听事件=>产生渐隐渐显效果
合成层

页面的绘制并不一定为在内存中的单层画面绘制,有时浏览器会将一帧画面绘制为多层画面,然后将若干层画面合并成一张图片显示到屏幕上。
将页面分层可以更好的区分开页面中静态部分和动态部分的绘制。

在 Blink 和 WebKit 内核的浏览器中,具有 transition 或 animation 的 opacity 元素,渲染层被提升为合成层。
translateZ(0) 或 translate3d(0,0,0)可以人为强制创建合成层。

而元素提升为合成层后,transform 和 opacity 不会触发 重绘制。如果不是合成层,则会触发重绘。

因为透明度改变后,GPU在绘制页面时可以改变之前画好的页面的透明值,而无需整体的重绘。
但是这个被修改的opacity必须为一个单独的图层,否则图层中的其他节点也会被重绘。

transition

opacity

逐渐过度的渐隐渐显

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <style>
    .blue{ 
    	width: 200px;
    	height: 200px;
    	background: blue;
    	transition: 1s;
    	}
  </style>
</head>
<body>
    <div class="blue" id="target"></div>
    <script>
        var flag = false;
        setInterval(function () {
            flag = !flag;
            target.style.opacity = flag ? 0 : 1;
        },1000)
    </script>
</body>
</html>

visibility

离散效果的延迟闪烁

可以将visibility : hidden 看成 visibility : 0
并且将visibility : visible 看成 visibility : 1;
visibility的值大于0时,元素就被显示。所以尽管visibility的值是从0到1平滑过度的,但是展示效果并不平滑。
在鼠标移进元素范围内的一秒后,visibility的值才为0,元素的隐藏效果被延迟。
而元素再次移动后,visibility的值迅速变为一个大于0的值,元素的展现效果不延迟。

<!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 至 visible 的方法

因为元素visibility : hidden时,监听的事件不会被触发。所以当设置visibility : visible 时,不可以直接绑定在 hidden 的元素上。

使用 a 控制其他元素样式的方法
使用a控制a的子元素 b
.a:hover .b {
        background-color:blue;
    }
使用a控制a的兄弟| 同级元素 c
.a:hover + .c {
        color:red;
    }
使用a控制a的就近元素d
.a:hover ~ .d {
        color:pink;
    }

红色方块控制蓝色方块的显示。
当鼠标移入红色方块时,蓝色方块visibility:visible
当鼠标移出红色方块1s后,蓝色方块visibility:hidden
移入蓝色方块区域不触发事件

<!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

display不支持transition,且会使transition失效。
因为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;
        display:none;
        transition:1s
    }
    .blue:hover .yellow{
        opacity:1;
        display:block;
    }
  </style>
 </head>
 <body>
    <div class='blue'>
        <div class='yellow'></div>
    </div>
 </body>
</html>

如果需要子元素出现渐隐渐显效果,只能使用visibility而不能使用display。

或者使用setTimeOut函数

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);
        })
  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值