博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

display:none和transition冲突了……

Posted on 2021-05-25 12:22  kpi311  阅读(478)  评论(0编辑  收藏  举报

前言

经过两天的思考终于在这个问题上算是告一段落,于是写下这篇文章希望有缘人能够指点一二。

起因

闲来无事用原生js写了个静态的轮播图,想要用css给图片元素添加上transition:opacity动画实现淡入淡出的效果,结果发现动画没有触发。

网上搜索一番用内联样式解决了问题,于是认为是图片上display:nonedisplay:block的切换触发了reflow导致transition失效了。

经过

一天之后,又写了个hover改变伪元素border的width的特效。

写完之后细想,不好,width改变必然触发reflow1,为什么transition能正常工作?我昨天的思路有问题呀。

这个回答2里说,因为display:none的元素转换为display:block之后没有transition动画需要的初始值,所以不触发动画。建议使用height:0height:auto的切换来达到效果。

我试了一下,很对,但是为什么呢?

渲染流程

大胆假设,小心求证。既然reflow没有问题,跟着浏览器渲染的路径上溯,可能问题出在了DOM Tree -> Render Tree这个过程中。

求助百度之后,看到这篇文章的解释3,对味了。display:none的节点和head节点不会被挂到render tree上。换句话说,attachment没做,在css文件中指定的css rules不会被附加到dom元素上。这就解释了为什么没有初始值,因为根本不存在css。而回过头来,内联样式因为在节点上,所以DOM parsing的时候就一并处理并附加了(推迟到attachment不合适吧?),这样transition动画才有了属性的初始值。

可以很轻松地通过代码验证。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test none elements</title>
    <style>
        .main{
            display: none;
            background: #00AAFF;
            width: 300px;
            line-height: 36px;
            box-sizing: border-box;
            color: #FFF;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <div class="main" style="opacity: 1;">
        <span>Hello</span>
    </div>
    <div class="main">
        <span>Hello</span>
    </div>
    <script>
        const [main, main1] = document.getElementsByClassName('main')
        console.log(main)
        console.log(main1)
    </script>
</body>
</html>

在console中可以访问到这两个全局变量mainmain1

main.style.opacity //"1"
main1.style.opacity //""

效果

效果如图。如果继续查看节点的style属性,就会发现,内部样式表中设置的属性都不存在,没有被附加到DOM节点上。

总结

或许使用异步方法等待元素进入到render树后再更改属性也可以达到效果?

参考资料

  1. https://csstriggers.com/width
  2. https://stackoverflow.com/questions/49269614/why-does-reflow-need-to-be-triggered-for-css-transitions
  3. https://blog.csdn.net/weixin_43294560/article/details/103394794