一、现状描述
有一个元素设置了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果然是越来越强了。
继续学习,保持不懈。
顺便帮忙分享下,谢啦~
(本篇完)