我确定必须先问过这个问题,并且已经找到相关问题,但我似乎不太想破解。
我有一个接收类的元素,然后接收一个类。稍后,当删除该类时,它应该还原(动画)回到其原始宽度。
let el = document.querySelector('#side-bar');
el.addEventListener('click', evt => el.classList.toggle('contracted'));
#side-bar {
height: 100%;
width: 75px;
background: red;
position: fixed;
left: 0;
top: 0;
}
#side-bar.contracted {
animation: .5s side-bar-contract forwards;
}
#side-bar:not(.contracted) {
animation: .5s side-bar-expand forwards;
}
@keyframes side-bar-expand {
to {
width: 350px;
}
}
@keyframes side-bar-contract {
to {
width: 75px;
}
}
<div id='side-bar' class='contracted'></div>
扩展动画效果很好。但是不会出现还原动画。它只是恢复其原始属性,没有动画。
我在做什么错了?
[编辑]
好吧,我显然应该提到为什么我不使用transition
来做到这一点。这是一系列依序运行的依存动画的一部分。我的理解是,对于animation
而言,这种按时间顺序排列的微不足道的情况要好于transition
。
答案 0 :(得分:4)
更新 :(开始时删除动画)
let init = 0,
el = document.querySelector('#side-bar');
el.addEventListener('click', function() {
if (init < 1) {
init++;
el.classList.remove("init");
el.classList.add('contracted');
}
el.classList.toggle('contracted');
});
#side-bar {
height: 100%;
width: 75px;
background: #d4653c;
position: fixed;
left: 0;
top: 0;
padding: .8rem;
}
#side-bar:not(.init) {
animation: .5s side-bar-expand forwards;
}
#side-bar.contracted {
animation: .5s side-bar-contract forwards;
}
@keyframes side-bar-expand {
to {
width: 350px;
}
}
@keyframes side-bar-contract {
from {
width: 350px;
}
}
<div id='side-bar' class='init'>Click me</div>
只需将to
中的from
更改为side-bar-contract
@keyframes side-bar-expand { to { width: 350px; } }
@keyframes side-bar-contract { from { width: 350px; } }
let el = document.querySelector('#side-bar');
el.addEventListener('click', evt => el.classList.toggle('contracted'));
#side-bar {
height: 100%;
width: 75px;
background: #d4653c;
position: fixed;
left: 0;
top: 0;
padding: .8rem;
}
#side-bar:not(.contracted) {
animation: .5s side-bar-expand forwards;
}
#side-bar.contracted {
animation: .5s side-bar-contract forwards;
}
@keyframes side-bar-expand {
to {
width: 350px;
}
}
@keyframes side-bar-contract {
from {
width: 350px;
}
}
<div id='side-bar' class='contracted'>Click me</div>
答案 1 :(得分:2)
为什么不只使用过渡动画:
let el = document.querySelector('#side-bar');
el.addEventListener('click', evt => el.classList.toggle('contracted'));
#side-bar {
height: 100%;
width: 350px; /* have width at 350px when not contracted */
background: #d4653c;
position: fixed;
left: 0;
top: 0;
padding: .8rem;
transition: width .5s; /* animate the width */
}
#side-bar.contracted {
width: 75px;
}
<div id='side-bar' class='contracted'>Click me</div>
如果您需要使用关键帧,则需要以350px开始第二个关键帧-您以75到75的水平开始,这就是为什么它没有动画:
let el = document.querySelector('#side-bar');
el.addEventListener('click', evt => el.classList.toggle('contracted'));
#side-bar {
height: 100%;
width: 75px;
background: #d4653c;
position: fixed;
left: 0;
top: 0;
padding: .8rem;
}
#side-bar:not(.contracted) {
animation: .5s side-bar-expand forwards;
}
#side-bar.contracted {
animation: .5s side-bar-contract forwards;
}
@keyframes side-bar-expand {
to {
width: 350px;
}
}
@keyframes side-bar-contract {
0% {
width: 350px;
}
100% {
width: 75px;
}
}
<div id='side-bar' class='contracted'>Click me</div>
答案 2 :(得分:1)
首先,我建议您使用悬停样式和css transition
来实现此目的,而不要使用动画来实现像对单个属性设置动画这样的简单操作。
.class {
width: 400px;
transition: width 1500ms ease-in-out;
}
.class:hover {
width: 100px;
}
CSS过渡实际上将在过渡过程中部分停止,并为您恢复初始大小。
第二,我建议您不要为CSS中的width
属性设置动画或过渡。 Here's a great article about what properties you should avoid animating。
如果您需要延迟过渡而不发生在其他元素上,则可以使用transition-delay
属性。此属性也可以应用于悬停效果……包括对父元素的悬停效果。因此,在给定的时间,您可能会在播放多种悬停效果,以实现所需的效果。