CSS动画-鼠标移出时恢复

时间:2018-11-26 16:28:53

标签: css css3 animation css-animations

我确定必须先问过这个问题,并且已经找到相关问题,但我似乎不太想破解。

我有一个接收类的元素,然后接收一个类。稍后,当删除该类时,它应该还原(动画)回到其原始宽度。

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>

扩展动画效果很好。但是不会出现还原动画。它只是恢复其原始属性,没有动画。

Fiddle

我在做什么错了?

[编辑]

好吧,我显然应该提到为什么我不使用transition来做到这一点。这是一系列依序运行的依存动画的一部分。我的理解是,对于animation而言,这种按时间顺序排列的微不足道的情况要好于transition

3 个答案:

答案 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属性。此属性也可以应用于悬停效果……包括对父元素的悬停效果。因此,在给定的时间,您可能会在播放多种悬停效果,以实现所需的效果。