Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent css keyframe animation to run on page load?

I have a div in which I animate the content:

#container {   position: relative;   width: 100px;   height: 100px;   border-style: inset; } #content {   visibility: hidden;   -webkit-animation: animDown 1s ease;   position: absolute;   top: 100px;   width: 100%;   height: 100%;   background-color: lightgreen; } #container:hover #content {   -webkit-animation: animUp 1s ease;   animation-fill-mode: forwards;   -webkit-animation-fill-mode: forwards; } @-webkit-keyframes animUp {   0% {     -webkit-transform: translateY(0);     visibility: hidden;     opacity: 0;   }   100% {     -webkit-transform: translateY(-100%);     visibility: visible;     opacity: 1;   } } @-webkit-keyframes animDown {   0% {     -webkit-transform: translateY(-100%);     visibility: visible;     opacity: 1;   }   100% {     -webkit-transform: translateY(0);     visibility: hidden;     opacity: 0;   } }
<div id="container">   <div id="content"></div> </div>

On hover, the content slides into the container div. When I refresh the page and the page loads, the #content's animDown animation will run, and I'd prefer it to run only after a hover event.

Is there a way to do this pure CSS, or I have to figure something out in JS?

http://jsfiddle.net/d0yhve8y/

like image 451
Szabolcs Avatar asked Jan 14 '15 08:01

Szabolcs


People also ask

How do you stop transitions on page load?

First we'll add an event listener to the DOMContentLoaded event (also known as page load). Next we find the CSS class that disables the transitions . preload-transitions . Lastly, once we know the DOM element, we remove the class from it.

How do you freeze an animation in CSS?

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.

How do you delay start animation in CSS?

CSS Animation Delay Syntax The CSS animation-delay property has the following syntax: animation-delay: [time] | initial | inherit; As you can see, there are three possible values: time, initial, and inherit. The first option is [time], which is the number of seconds or milliseconds before the animation starts.

Does CSS animations affect performance?

TL;DR # Take care that your animations don't cause performance issues; ensure that you know the impact of animating a given CSS property. Animating properties that change the geometry of the page (layout) or cause painting are particularly expensive. Where you can, stick to changing transforms and opacity.


2 Answers

I always set preload class to body with animation time value 0 and its working pretty well. I have some back going transitions so I have to remove load animation to them too. I solved this by temporary setting animation time to 0. You can change transitions to match yours.

HTML

... <body class="preload">...

CSS is setting animation to 0s

body.preload *{ animation-duration: 0s !important; -webkit-animation-duration: 0s !important; transition:background-color 0s, opacity 0s, color 0s, width 0s, height 0s, padding 0s, margin 0s !important;} 

JS will remove class after some delay so animations can happen in normal time :)

setTimeout(function(){     document.body.className=""; },500); 
like image 97
Tominator Avatar answered Sep 20 '22 20:09

Tominator


Solution 1 - Add down animation on first hover

Probably the best option is to not put the down animation on until the user has hovered over the container for the first time.

This involves listening to the mouseover event then adding a class with the animation at that point, and removing the event listener. The main (potential) downside of this is it relies on Javascript.

;(function(){      var c = document.getElementById('container');      function addAnim() {          c.classList.add('animated')          // remove the listener, no longer needed          c.removeEventListener('mouseover', addAnim);      };        // listen to mouseover for the container      c.addEventListener('mouseover', addAnim);  })();
#container {      position:relative;      width:100px;      height:100px;      border-style:inset;  }  #content {      position:absolute;      top:100px;      width:100%;      height:100%;      background-color:lightgreen;      opacity:0;  }    /* This gets added on first mouseover */  #container.animated #content {      -webkit-animation:animDown 1s ease;  }    #container:hover #content {      -webkit-animation:animUp 1s ease;      animation-fill-mode:forwards;      -webkit-animation-fill-mode:forwards;  }    @-webkit-keyframes animUp {      0% {          -webkit-transform:translateY(0);          opacity:0;      }      100% {          -webkit-transform:translateY(-100%);          opacity:1;      }  }  @-webkit-keyframes animDown {      0% {          -webkit-transform:translateY(-100%);          opacity:1;      }      100% {          -webkit-transform:translateY(0);          opacity:0;      }  }
<div id="container">      <div id="content"></div>  </div>

Solution 2 - play animation hidden

Another way around this is to initially hide the element, make sure the animation plays while it is hidden, then make it visible. The downside of this is that the timing could be slightly off and it is made visible too early, and also the hover isn't available straight away.

This requires some Javascript which waits for the length of the animation and only then makes #content visible. This means you also need to set the initial opacity to 0 so it doesn't appear on load and also remove the visibility from the keyframes - these aren't doing anything anyway:

// wait for the animation length, plus a bit, then make the element visible  window.setTimeout(function() {      document.getElementById('content').style.visibility = 'visible';  }, 1100);
#container {      position:relative;      width:100px;      height:100px;      border-style:inset;  }    #content {      visibility:hidden;      -webkit-animation:animDown 1s ease;      position:absolute;      top:100px;      width:100%;      height:100%;      background-color:lightgreen;      opacity:0;  }    #container:hover #content {      -webkit-animation:animUp 1s ease;      animation-fill-mode:forwards;      -webkit-animation-fill-mode:forwards;  }    @-webkit-keyframes animUp {      0% {          -webkit-transform:translateY(0);          opacity:0;      }      100% {          -webkit-transform:translateY(-100%);          opacity:1;      }  }    @-webkit-keyframes animDown {      0% {          -webkit-transform:translateY(-100%);          opacity:1;      }      100% {          -webkit-transform:translateY(0);          opacity:0;      }  }
<div id="container">      <div id="content"></div>  </div>

Solution 3 - Use transitions

In your scenario, you can make this CSS only by replacing the keyframes with a transition instead, so it starts with opacity:0 and just the hover has a change in opacity and the transform:

#container {      position:relative;      width:100px;      height:100px;      border-style:inset;  }    #content {      position:absolute;      top:100px;      width:100%;      height:100%;      background-color:lightgreen;        /* initial state - hidden */      opacity:0;      /* set properties to animate - applies to hover and revert */      transition:opacity 1s, transform 1s;  }    #container:hover #content {      /* Just set properties to change - no need to change visibility */      opacity:1;      -webkit-transform:translateY(-100%);      transform:translateY(-100%);  }
<div id="container">      <div id="content"></div>  </div>
like image 42
Rhumborl Avatar answered Sep 20 '22 20:09

Rhumborl