I would like a div to animate to the right when a button is clicked, then animate again to the left when the same button is clicked. I would like to use only one keyframes
declaration. Is this possible by swapping classes?
I've tried this in CodePen, but unfortunately, the div snaps back after the first animation, then refuses to animate the second time.
I'm not using CSS transitions because I want to be able to use features of CSS animations like a bouncing effect.
window.addEventListener("load", function() {
var movedOver = false;
document.querySelector("button").addEventListener("click", function() {
var buttonEl = document.querySelector(".one");
if (movedOver) {
buttonEl.classList.remove("do-the-slide");
buttonEl.classList.add("do-the-slide-back");
} else {
buttonEl.classList.remove("do-the-slide-back");
buttonEl.classList.add("do-the-slide");
}
});
});
.container {
position: absolute;
perspective: 800px;
>div {
position: absolute;
padding: 20px;
text-align: center;
width: 100px;
}
>div.do-the-slide {
animation: moveOver 1s ease-out;
}
>div.do-the-slide-back {
animation: moveOver 1s reverse ease-out;
}
>.one {
background: red;
}
}
button {
margin-top: 100px;
}
@keyframes moveOver {
from {
transform: translateX(0px);
}
to {
transform: translateX(100px);
}
}
<div class="container">
<div class="one">One</div>
</div>
<button>Clicky</button>
Codepen: http://codepen.io/anon/pen/Vaadao
Alright, so after fiddling with this for a while, I've come up with what I consider an acceptable solution for using one keyframes declaration to drive both directions of animations. The key to this was forcing the browser essentially reset through a redraw, as explained here: https://css-tricks.com/restart-css-animation/ (thank you Jacob Gray for posting that reference).
Once I got that working with the reset, I used javascript (yes, this requires javascript) to add the reverse direction when animating back (this could be in a separate class and just add that className).
And, it works. I'm now able to animate in both directions using one keyframes declaration. Pretty snazzy, and drastically minimizes the css code.
window.addEventListener("load", function() {
var movedOver = false;
var direction = "";
document.querySelector("button").addEventListener("click", function() {
var el = document.querySelector(".one");
el.classList.remove("do-the-slide");
el.offsetWidth = el.offsetWidth;
if (direction === "toRight") {
direction = "toLeft";
el.style.animationDirection = "reverse";
} else {
direction = "toRight";
el.style.animationDirection = "";
}
el.classList.add("do-the-slide");
});
});
.container {
position: absolute;
perspective: 800px;
>div {
position: absolute;
padding: 20px;
text-align: center;
width: 100px;
}
>div.do-the-slide {
animation: moveOver 1s ease-in-out;
animation-fill-mode: forwards;
}
>.one {
background: red;
}
}
button {
margin-top: 100px;
}
@keyframes moveOver {
from {
transform: translate3d(0px, 0, 0);
}
20% {
transform: translate3d(-20px, 0, 0);
}
80% {
transform: translate3d(120px, 0, 0);
}
to {
transform: translate3d(100px, 0, 0);
}
}
<div class="container">
<div class="one">One</div>
</div>
<button>Clicky</button>
CodePen: http://codepen.io/risingtiger/pen/zqqMpv
Maybe you are looking for forwards
, but even then, a transition will be needed to make it simple.
p span {
display: inline-block;
transition: 1s;
}
p:hover span {
animation: 1s moveOver forwards;
}
@keyframes moveOver {
to {
transform: translateX(100px);
}
<p><span>span</span>
</p>
I f you want to use a single animation, you will eventually have to deal with paused and steps and i m not even sure that will be easy to handle or possible. I see no fun here :)
for a bounce effect, final value at 50% should be good enough:
p span {
display: inline-block;
transition: 1s;
}
p:hover span {
animation: 2s moveOver infinite;
}
@keyframes moveOver {
50% {
transform: translateX(100px);
}
<p><span>span</span>
</p>
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