CSS animation: pausing - css

I have a simple CSS3 animation which I would like to pause on hover.
Here is a simplified version:
h1 {
animation-name: test 3000ms infinite alternate;
}
#keyframes test {
from {
transform: translate(0,0);
}
to {
transform: translate(100px,0);
}
}
h1:hover {
animation: paused;
}
It works, but pausing means jumping back to the 0% state. Is there a way to either (a) pause in the current state of (b) resetting more gracefully, such as running through one final loop?
Thanks

Use animation-play-state as below:
h1 {
animation-name: test;
animation-duration:3000ms;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-play-state:running;/*running normally*/
}
h1:hover {
animation-play-state:paused; /*paused when hover*/
}
DEMO
Note - The animation-play-state property is not supported in Internet Explorer 9 and earlier versions.

Related

Fade paragraphs in incrementally with CSS Animation [duplicate]

I'm running an animation on some elements that are set to opacity: 0; in the CSS. The animation class is applied onClick, and, using keyframes, it changes the opacity from 0 to 1 (among other things).
Unfortunately, when the animation is over, the elements go back to opacity: 0 (in both Firefox and Chrome). My natural thinking would be that animated elements maintain the final state, overriding their original properties. Is this not true? And if not, how can I get the element to do so?
The code (prefixed versions not included):
#keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; }
50% { transform:scale(1.2); opacity:0.5; }
100% { transform:scale(1.0); opacity:1.0; }
}
Try adding animation-fill-mode: forwards;. For example, the shorthand would be used like this:
-webkit-animation: bubble 1.0s forwards; /* for less modern browsers */
animation: bubble 1.0s forwards;
If you are using more animation attributes the shorthand is:
animation: bubble 2s linear 0.5s 1 normal forwards;
This gives:
bubble animation name
2s duration
linear timing-function
0.5s delay
1 iteration-count (can be 'infinite')
normal direction
forwards fill-mode (set 'backwards' if you want to have compatibility to use the end position as the final state[this is to support browsers that has animations turned off]{and to answer only the title, and not your specific case})
Available timing-functions:
ease | ease-in | ease-out | ease-in-out | linear | step-start | step-end
Available directions
normal | reverse | alternate | alternate-reverse
IF NOT USING THE SHORT HAND VERSION: Make sure the animation-fill-mode: forwards is AFTER the animation declaration or it will not work...
animation-fill-mode: forwards;
animation-name: appear;
animation-duration: 1s;
animation-delay: 1s;
vs
animation-name: appear;
animation-duration: 1s;
animation-fill-mode: forwards;
animation-delay: 1s;
Use
animation-fill-mode: forwards;
animation-fill-mode: forwards;
The element will retain the style values that is set by the last keyframe (depends on animation-direction and animation-iteration-count).
Note: The #keyframes rule is not supported in Internet Explorer 9 and earlier versions.
Working example
div {
width: 100px;
height: 100px;
background: red;
position :relative;
-webkit-animation: mymove 3ss forwards; /* Safari 4.0 - 8.0 */
animation: bubble 3s forwards;
/* animation-name: bubble;
animation-duration: 3s;
animation-fill-mode: forwards; */
}
/* Safari */
#-webkit-keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; left:0}
50% { transform:scale(1.2); opacity:0.5; left:100px}
100% { transform:scale(1.0); opacity:1.0; left:200px}
}
/* Standard syntax */
#keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; left:0}
50% { transform:scale(1.2); opacity:0.5; left:100px}
100% { transform:scale(1.0); opacity:1.0; left:200px}
}
<h1>The keyframes </h1>
<div></div>
I had an issue using forwards: at least in Chrome, even after the animation ended, the renderer was still sucking up graphics resources, making the application less responsive.
An approach that does not cause this trouble is by using an EventListener.
CSS animations emit events, so you can use the animationend event to intervene when the animation ends.
CSS
.fade_in {
animation: fadeIn 2s;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
JavaScript
const element = document.getElementById("element-to-be-animated");
element.addEventListener("animationend", () => {
// Set your final state here. For example:
element.style["opacity"] = 1;
}, { once: true });
The option once: true tells the engine to remove the event listener after its execution, leaving your application fresh and clean.
I have created a JSFiddle to show how it works.

Finish infinite iterations cycle and stop the animation with CSS

I have an animation that has an infinite iterations count:
.spinner {
animation: spinnerAnimation 2s linear infinite;
}
What I want is to make the animation finish the current animation cycle and stop it on a button click (not really on a button click, but this is to make things easier to understand):
$("button").click(function() {
$(".spinner").addClass("stop");
})
This will add a stop class to the spinner:
.spinner.stop {
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
It doesn't work really smooth, but I don't care about smoothness much in this case:
http://codepen.io/Deka87/pen/OXZvdm
The only problem is that this won't stop the animation in IE edge, i.e. things don't work in IE (versions that support animations). Any ideas?
PS: animation-play-state: pause; is not what I need, because this won't make the animation finish the current animation cycle, but pause it in its current position instead.
PSS: I am really looking for a CSS only solution, i.e. make it work inside .spinner.stop{}.
You had a problem with the name of your keyframe name - spinnerAnimation vs preloaderAnimation
The only way I was able to set IE to stop the animation was to set animation: none; inside the .stop class:
$("button").click(function() {
$(".spinner").addClass("stop");
})
.spinner {
width: 30px; height: 30px;
background: green;
animation: spinnerAnimation 2s linear infinite;
}
.spinner.stop {
-webkit-animation-iteration-count: 1;
animation: none;
}
button {
margin-top: 20px;
}
#-webkit-keyframes spinnerAnimation {
0% {
-webkit-transform: rotate(0);
}
100% {
-webkit-transform: rotate(360deg);
}
}
#keyframes spinnerAnimation {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="spinner"></div>
<button>Stop spinner</button>

How to not initialize CSS3 animation when launching another one or visiting another page?

I would like to know how to avoid the keyframe animation to be automatically reseted after launching anoher one or visiting another tab of my browser.
#-webkit-keyframes play1 {
0% {
-webkit-transform: translate(0px,0);
}
50% {
-webkit-transform: translate(-60px,0) rotate(-1080deg) scale(1.5);
}
100% {
-webkit-transform: translate(-120px,0) rotate(-2060deg) scale(1);
}
}
.play1 {
-webkit-animation-name: play1;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: linear;
-webkit-animation-direction: alternate;
}
#-webkit-keyframes play2 {
0% {
-webkit-transform: translate(0px,0);
}
50% {
-webkit-transform: translate(-60px,0) rotate(-1080deg) scale(3);
}
100% {
-webkit-transform: translate(-120px,0) rotate(-2060deg) scale(1);
}
}
.play2 {
-webkit-animation-name: play2;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: linear;
-webkit-animation-direction: alternate;
}
On this example, if i launch the animation play1 then play2 by adding the respective classes on the elements, the position of the element accoding to the play1 animation is automatically reseted to its initial position (if i visite another tab and come back, all my elements are in their initial position), how to avoid this?
Even worse on mozilla, the animation is reseted when its over.
I don't have this behavior by using the animation-iteration-count: infinite; property, but i just want to play it one time.
The property which enables this is: animation-fill-mode: forwards

css3 animations hard blink (no fade inbetween frames)

trying to flash three elements in a row with css3 animations. i've got it running, but there is a fade for each frame and i'd like to remove it. ideally each element stays visible for 1s, then hides immediately.
i've tried setting the animation with frames at 0% and 99% for opacity:1 and 100% for opacity: 0 but still no luck.
i hope theres a way to remove the fade!
webkit js fiddle
CSS:
.motion.play .frame {
-webkit-animation-name: flash;
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: linear;
}
.frame:nth-of-type(2) {
-webkit-animation-delay: 1s;
}
.frame:nth-of-type(3) {
-webkit-animation-delay: 2s;
}
#-webkit-keyframes flash {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
Just define your animation so that it keeps one state as long as possible and then switches to the other one as fast as possible. Like this:
#-webkit-keyframes flash {
0% { opacity: 1; }
49% { opacity: 1; }
50% { opacity: 0; }
100% { opacity: 0; }
}
Use proper animation-timing-function:
http://jsfiddle.net/rfGDD/1/ (WebKit only)
.motion.play .frame {
-webkit-animation-name: flash;
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: normal; /* not "linear" */
-webkit-animation-fill-mode:forwards;
-webkit-animation-timing-function:steps(3, end);
}
MDN document on fill-mode
MDN document on direction
MDN document on steps() timing function
Edit:
Oops, just realized the logical flaw.
Revised: http://jsfiddle.net/rfGDD/3/ (WebKit only)
In addition to the above change, change the flash animation to following:
#-webkit-keyframes flash {
0% {
opacity: 1;
}
33% {
opacity: 0;
}
100% {
opacity: 0;
}
}
The problem is, the animation plays 3 seconds, but each element need to stay in the opacity:0 state after second #1, so I need to split the animation into 2 stages (with the timing length ratio 1:2), so elements can look like they stays in final stage for 2 seconds.
You may keep the opacity for the longest period and change it very quickly.
Try this:
.blinkMe {
animation: blink 1s linear infinite;
}
#keyframes blink {
0%,50% {
opacity: 0;
}
51%,100% {
opacity: 1;
}
}

Maintaining the final state at end of a CSS animation

I'm running an animation on some elements that are set to opacity: 0; in the CSS. The animation class is applied onClick, and, using keyframes, it changes the opacity from 0 to 1 (among other things).
Unfortunately, when the animation is over, the elements go back to opacity: 0 (in both Firefox and Chrome). My natural thinking would be that animated elements maintain the final state, overriding their original properties. Is this not true? And if not, how can I get the element to do so?
The code (prefixed versions not included):
#keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; }
50% { transform:scale(1.2); opacity:0.5; }
100% { transform:scale(1.0); opacity:1.0; }
}
Try adding animation-fill-mode: forwards;. For example, the shorthand would be used like this:
-webkit-animation: bubble 1.0s forwards; /* for less modern browsers */
animation: bubble 1.0s forwards;
If you are using more animation attributes the shorthand is:
animation: bubble 2s linear 0.5s 1 normal forwards;
This gives:
bubble animation name
2s duration
linear timing-function
0.5s delay
1 iteration-count (can be 'infinite')
normal direction
forwards fill-mode (set 'backwards' if you want to have compatibility to use the end position as the final state[this is to support browsers that has animations turned off]{and to answer only the title, and not your specific case})
Available timing-functions:
ease | ease-in | ease-out | ease-in-out | linear | step-start | step-end
Available directions
normal | reverse | alternate | alternate-reverse
IF NOT USING THE SHORT HAND VERSION: Make sure the animation-fill-mode: forwards is AFTER the animation declaration or it will not work...
animation-fill-mode: forwards;
animation-name: appear;
animation-duration: 1s;
animation-delay: 1s;
vs
animation-name: appear;
animation-duration: 1s;
animation-fill-mode: forwards;
animation-delay: 1s;
Use
animation-fill-mode: forwards;
animation-fill-mode: forwards;
The element will retain the style values that is set by the last keyframe (depends on animation-direction and animation-iteration-count).
Note: The #keyframes rule is not supported in Internet Explorer 9 and earlier versions.
Working example
div {
width: 100px;
height: 100px;
background: red;
position :relative;
-webkit-animation: mymove 3ss forwards; /* Safari 4.0 - 8.0 */
animation: bubble 3s forwards;
/* animation-name: bubble;
animation-duration: 3s;
animation-fill-mode: forwards; */
}
/* Safari */
#-webkit-keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; left:0}
50% { transform:scale(1.2); opacity:0.5; left:100px}
100% { transform:scale(1.0); opacity:1.0; left:200px}
}
/* Standard syntax */
#keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; left:0}
50% { transform:scale(1.2); opacity:0.5; left:100px}
100% { transform:scale(1.0); opacity:1.0; left:200px}
}
<h1>The keyframes </h1>
<div></div>
I had an issue using forwards: at least in Chrome, even after the animation ended, the renderer was still sucking up graphics resources, making the application less responsive.
An approach that does not cause this trouble is by using an EventListener.
CSS animations emit events, so you can use the animationend event to intervene when the animation ends.
CSS
.fade_in {
animation: fadeIn 2s;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
JavaScript
const element = document.getElementById("element-to-be-animated");
element.addEventListener("animationend", () => {
// Set your final state here. For example:
element.style["opacity"] = 1;
}, { once: true });
The option once: true tells the engine to remove the event listener after its execution, leaving your application fresh and clean.
I have created a JSFiddle to show how it works.

Resources