Dan
Dan

Reputation: 6514

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; }
}

Upvotes: 541

Views: 390524

Answers (5)

Christofer Vilander
Christofer Vilander

Reputation: 18062

Try adding animation-fill-mode: forwards;. For example, the shorthand would be used like this:

animation: bubble 1.0s forwards;

https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode

Upvotes: 886

agiopnl
agiopnl

Reputation: 1354

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

Upvotes: 102

Luca Fagioli
Luca Fagioli

Reputation: 13359

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.

Upvotes: 4

Deepu Reghunath
Deepu Reghunath

Reputation: 9713

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>

Upvotes: 15

Taylor A. Leach
Taylor A. Leach

Reputation: 2324

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;

Upvotes: 41

Related Questions