So, it is possible to have reverse animation on mouse out such as:
.class{
transform: rotate(0deg);
}
.class:hover{
transform: rotate(360deg);
}
but, when using @keyframes animation, I couldn't get it to work, e.g:
.class{
animation-name: out;
animation-duration:2s;
}
.class:hover{
animation-name: in;
animation-duration:5s;
animation-iteration-count:infinite;
}
@keyframe in{
to {transform: rotate(360deg);}
}
@keyframe out{
to {transform: rotate(0deg);}
}
What is the optimal solution, knowing that I'd need iterations and animation itself?
http://jsfiddle.net/khalednabil/eWzBm/
By setting the animation-play-state to paused on hover, the animation will pause, your click targets will stop moving, and your users will be happy.
I think that if you have a to
, you must use a from
.
I would think of something like :
@keyframe in {
from: transform: rotate(0deg);
to: transform: rotate(360deg);
}
@keyframe out {
from: transform: rotate(360deg);
to: transform: rotate(0deg);
}
Of course must have checked it already, but I found strange that you only use the transform
property since CSS3 is not fully implemented everywhere. Maybe it would work better with the following considerations :
@-webkit-keyframes
, no particuliar version needed@-webkit-keyframes
since version 5+@keyframes
since version 16 (v5-15 used @-moz-keyframes
)@-webkit-keyframes
version 15-22 (only v12 used @-o-keyframes
)@keyframes
since version 10+EDIT :
I came up with that fiddle :
http://jsfiddle.net/JjHNG/35/
Using minimal code. Is it approaching what you were expecting ?
Its much easier than all this: Simply transition the same property on your element
.earth { width: 0.92%; transition: width 1s; }
.earth:hover { width: 50%; transition: width 1s; }
https://codepen.io/lafland/pen/MoEaoG
I don't think this is achievable using only CSS animations. I am assuming that CSS transitions do not fulfil your use case, because (for example) you want to chain two animations together, use multiple stops, iterations, or in some other way exploit the additional power animations grant you.
I've not found any way to trigger a CSS animation specifically on mouse-out without using JavaScript to attach "over" and "out" classes. Although you can use the base CSS declaration trigger an animation when the :hover ends, that same animation will then run on page load. Using "over" and "out" classes you can split the definition into the base (load) declaration and the two animation-trigger declarations.
The CSS for this solution would be:
.class {
/* base element declaration */
}
.class.out {
animation-name: out;
animation-duration:2s;
}
.class.over {
animation-name: in;
animation-duration:5s;
animation-iteration-count:infinite;
}
@keyframes in {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes out {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}
And using JavaScript (jQuery syntax) to bind the classes to the events:
$(".class").hover(
function () {
$(this).removeClass('out').addClass('over');
},
function () {
$(this).removeClass('over').addClass('out');
}
);
Creating a reversed animation is kind of overkill to a simple problem. What you need is:
animation-direction: reverse
However, this won't work on its own because animation spec forgot to add a way to restart the animation, so here is how you do it with the help of JS
let item = document.querySelector('.item')
// play normal
item.addEventListener('mouseover', () => {
item.classList.add('active')
})
// play in reverse
item.addEventListener('mouseout', () => {
item.style.opacity = 0 // avoid showing the init style while switching the 'active' class
item.classList.add('in-active')
item.classList.remove('active')
// force dom update
setTimeout(() => {
item.classList.add('active')
item.style.opacity = ''
}, 5)
item.addEventListener('animationend', onanimationend)
})
function onanimationend() {
item.classList.remove('active', 'in-active')
item.removeEventListener('animationend', onanimationend)
}
@keyframes spin {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(180deg);
}
}
div {
background: black;
padding: 1rem;
display: inline-block;
}
.item {
/* because span cant be animated */
display: block;
color: yellow;
font-size: 2rem;
}
.item.active {
animation: spin 1s forwards;
animation-timing-function: ease-in-out;
}
.item.in-active {
animation-direction: reverse;
}
<div>
<span class="item">ABC</span>
</div>
we can use requestAnimationFrame to reset animation and reverse it when browser paints in next frame.
Also use onmouseenter and onmouseout event handlers to reverse animation direction
As per
Any rAFs queued in your event handlers will be executed in the same frame. Any rAFs queued in a rAF will be executed in the next frame.
function fn(el, isEnter) {
el.className = "";
requestAnimationFrame(() => {
requestAnimationFrame(() => {
el.className = isEnter? "in": "out";
});
});
}
.in{
animation: k 1s forwards;
}
.out{
animation: k 1s forwards;
animation-direction: reverse;
}
@keyframes k
{
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
<div style="width:100px; height:100px; background-color:red"
onmouseenter="fn(this, true)"
onmouseleave="fn(this, false)"
></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With