这篇文章发布于 2024年06月30日,星期日,00:55,归类于 CSS相关。 阅读 6177 次, 今日 25 次 3 条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11245
本文可全文转载,独立域名个人网站无需授权,但需要保留原作者、出处以及文中链接,任何网站均可摘要聚合,商用请联系授权。
一、现状描述
有一个元素设置了display:none
隐藏,然后使用JS让其实现的时候,希望同时有透明度变化的动画效果,使用transition
属性是无效的。
如下代码示意:
<div id="element" class="element">占位内容</div>
.element { display: none; opacity: 0; transition: .2s; } .element.active { display: block; opacity: 1; }
// 让元素显示 element.classList.add('active');
此时元素是突然显示,而不是有透明度动画。
在之前,有两种方法:
- 元素先显示,透明度保持0,然后在下一个渲染绘制执行设置透明度为1.
- 使用CSS animation动画,代码参见:
.element.active { display: block; animation: fadeIn .2s both; } @keyframes { from { opacity: 0; } to { opacity: 1; } }
不过上面两种方法都比较麻烦,不如直接一个transition
属性来的方便。
那有没有什么办法让元素从display:none到display:block变化的时候,也有动画效果呢?
可以,最近各个现代浏览器支持了一个新的 CSS 属性名为transition-behavior
,可以实现这样的需求。
二、transition-behavior属性的语法和作用
语法如下:
transition-behavior: allow-discrete; transition-behavior: normal;
其中:
allow-discrete
表示允许离散的CSS属性也支持transition
过渡效果,其中,最具代表性的离散CSS属性莫过于display属性了。normal
就是之前的transition
过渡表现,除了visibility
这个我一直都认为是离散CSS的属性之外,其余离散CSS都没有过渡效果。,
使用案例
仅使用transition
属性,实现元素从 display:inline ↔ none 的过渡效果。
HTML如下所示:
<button id="trigger">图片显示与隐藏</button> <img id="target" src="1.jpg" />
通过toggle hidden属性实现显隐变化:
trigger.onclick = function () { target.toggleAttribute('hidden'); };
OK,最关键的CSS来了,很简单,几行代码就可以了:
img { transition: .25s allow-discrete; opacity: 1; } img[hidden] { opacity: 0; }
此时,点击按钮让图片隐藏的时候,就可以看到图片淡出的效果了,如下GIF动图所示:
酷啊~
当然,上面的CSS代码也可以分开书写:
transition-duration: .25s; transition-behavior: allow-discrete;
然而,再次点击按钮,希望其淡出显示的时候,却没有任何动画效果。
问题分析与解决
为何设置transition-behavior:allow-discrete
可以让动画display:none
在过渡时长结束之后才执行,因此,opacity的过渡动画可以肉眼可见。
但是从display:none
到display:block
的显示是突然的,在浏览器的渲染绘制层面,元素display计算值变成block和opacity设为1是在同一个渲染帧完成的,由于没有起始opacity,所以看不到动画效果。
那有没有什么办法让元素display显示的时候也有过渡效果呢?
还真有,可以使用全新的@starting-style
规则,专门解决此类问题的。
三、使用@starting-style规则声明过渡起点
@starting-style
顾名思义就是声明起始样式,专门用在transition过渡效果中。
例如上面的例子,要想让元素display显示的时候有淡出效果,很简单,再加三行代码就可以了:
img { transition: .25s allow-discrete; opacity: 1; @starting-style { opacity: 0; } }
或者不使用CSS嵌套语法,这样写也是可以的:
img { transition: .25s allow-discrete; opacity: 1; } @starting-style { img { opacity: 0; } }
此时,我们再点击按钮让图片显示,就可以看到图片是透明度动画显示的,如下MP4视频录屏所示(不动点击播放):
眼见为实,您可以狠狠地点击这里:CSS transition-behavior和@starting-style实现淡入淡出demo
不仅可以看到淡入淡出效果,还可以看到上面展示的仅淡出效果。
四、CSS越来越强了
本文要介绍的其实就2个东西,一个是transition-behavior:allow-discrete
可以让元素display:none
也可以有淡出效果,另外一个是@starting-style
规则,可以让元素不再是display:none
可以有淡入效果。
在实际的Web开发中,popover浮层和dialog对话框显隐的时候,都是基于display计算值实现的。
现在,有了transition-behavior
和@starting-style
规则,这些原生HTML元素的交互效果就可以更上一层楼,算是弥补了长久以来的不足,非常棒,CSS果然是越来越强了。
继续学习,保持不懈。
顺便帮忙下,谢啦~
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11245
(本篇完)
- 使用CSS revert全局关键字还原display显示元素 (0.370)
- CSS Nesting嵌套与@scope规则也太雷同了吧? (0.370)
- 小tip: transition与visibility (0.261)
- jQuery-innerfade内部列表自动淡入淡出插件 (0.185)
- CSS3背景图片透明叠加属性cross-fade简介 (0.185)
- 几种CSS渐变背景图片transtion动画方法 (0.076)
- cssSandpaper-兼容IE的CSS3 JavaScript库 (0.046)
- 您可能不知道的CSS元素隐藏“失效”以其妙用 (0.046)
- 小tip: 微博新版查看大图前后浏览的另外一种实现 (0.046)
- border-collapse与table td边框opacity透明度诡异解析 (0.046)
- “更多|收起”交互中渐进使用transition动画 (RANDOM - 0.030)
牛
@starting-style有个巨坑,虽然可以嵌套(而且支持@starting-style的浏览器一定支持css嵌套)
但,伪元素里不能嵌套!也就是dialog的::backdrop里写不了@starting-style!!!!得单独再外面写
大佬太强啦!