What is the best way to alternate the direction of a CSS3 animation on click without javascript?
I've been exploring checkbox hacks lately and trying to figure out a way to have only one set of keyframes instead of two sets for one going forward and one to come back. Is this possible? Or is there a way to do it with one set?
For instance I have the following keyframes:
@keyframes moveIt {
0% {
transform: translateX(0);
width: $size;
}
50% {
width: $size*1.2;
}
100% {
transform: translateX(50px);
width: $size;
}
}
@keyframes moveItBack {
100% {
transform: translateX(0);
width: $size;
}
50% {
width: $size*1.2;
}
0% {
transform: translateX(50px);
width: $size;
}
}
Any way to reduce this to only the first set? Then when coming back start from 100% and go back to 0%?
Here is an example of what I am trying to accomplish this on.
The key to restarting a CSS animation is to set the animation-name of an animation to 'none' and then setting it back to the original animation. As you can see this requires two steps. One to switch it to a different animation and one to set it back.
The only way to truly pause an animation in CSS is to use the animation-play-state property with a paused value. In JavaScript, the property is “camelCased” as animationPlayState and set like this: element. style.
CSS is not really meant to do something like this but there are some work-arounds
Optimally we could do something like the following because it makes sense logically
.bubble {
...
animation: moveIt .25s forwards ease-out;
}
input[type=checkbox]:checked ~ .bubble {
animation: moveIt .25s backwards ease-out;
}
However, you cannot reset or change to a different animation using pure CSS[1]. This is because elements are only allowed to have one animation each. You can reset it in javascript by using setTimeout
or cloning the element, but I assume you're trying to avoid that.
Thus, you're left with two options. The first is to ditch the change in size and just toggle the translateX
like so:
.bubble {
...
transition: all .25s ease-out;
}
input[type=checkbox]:checked ~ .bubble {
transform: translateX(50px);
}
The other option to retain the change in size is to do something a bit more involved. You can essentially fake the change of size by using pseudo elements. By toggling the animation of both opposite from each other, you can make the whole element look like it pulses each time. Demo
.bubble {
...
transition: all .25s ease-out;
}
.bubble:after, .bubble:before {
content:'';
position:absolute;
width:100%; height:100%;
background:inherit;
border-radius:inherit;
animation:'';
}
.bubble:before { animation:size .25s ease-out; }
input[type=checkbox]:checked ~ .bubble:before { animation:''; }
input[type=checkbox]:checked ~ .bubble {
transform: translateX(50px);
}
input[type=checkbox]:checked ~ .bubble:after {
animation:size .25s ease-out;
}
@keyframes size {
50% { transform:scale(1.2); }
}
I hope it makes sense!
[1]: As seen in the second option, it is possible, it just requires a state of removing the past animation. Sadly something like animation:''; animation:moveIt .25s backwards ease-out;
does not reset it
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