Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS Animation not going through all Keyframes

BackGround

I've been working to learn more about CSS animations. I've been primarily working with pre-built animations from libraries like animate.css . Most of the functions work great and I think I'm understanding the concepts and components better.

Issue

However, one of the animations from the that library, hinge, works on the animate.css site but not in my own fiddle. It doesn't outright fail, but it only makes 3 keyframe movements, while the example site makes 5-6. So it is using animations just not how I would expect.

I blame the keyframes in my title, because visually it does not appear to swing. I attribute this to keyframes not working, but this may be an oversimplification or I could be misunderstanding the issue, so be aware that is where that assumption comes from.

I have tested this with my primary browser Chrome v35, and a copy of IE 11 I have on my computer, commentors point out that FF 30 did not exhibit this issue. They also show that this could be related to it being a dependency, when it is defined explicitly, rather than pulled in through the animate.css cdn, it works in my browser.

Research

I've been doing general research to better understand CSS animations, this developer guide in particular has been helpful in understanding the basics and seeing how live examples work. these have been especially useful in conjunction with fiddles to see how modifications to those examples work.

More specific to this issue I pulled open the source to see how the css animations were defined. the code is published on github here. The specific keyframes for the hinge are below

@keyframes hinge {
  0% {
    -webkit-transform-origin: top left;
    -ms-transform-origin: top left;
    transform-origin: top left;
    -webkit-animation-timing-function: ease-in-out;
    animation-timing-function: ease-in-out;
  }

  20%, 60% {
    -webkit-transform: rotate3d(0, 0, 1, 80deg);
    -ms-transform: rotate3d(0, 0, 1, 80deg);
    transform: rotate3d(0, 0, 1, 80deg);
    -webkit-transform-origin: top left;
    -ms-transform-origin: top left;
    transform-origin: top left;
    -webkit-animation-timing-function: ease-in-out;
    animation-timing-function: ease-in-out;
  }

  40%, 80% {
    -webkit-transform: rotate3d(0, 0, 1, 60deg);
    -ms-transform: rotate3d(0, 0, 1, 60deg);
    transform: rotate3d(0, 0, 1, 60deg);
    -webkit-transform-origin: top left;
    -ms-transform-origin: top left;
    transform-origin: top left;
    -webkit-animation-timing-function: ease-in-out;
    animation-timing-function: ease-in-out;
    opacity: 1;
  }

  100% {
    -webkit-transform: translate3d(0, 700px, 0);
    -ms-transform: translate3d(0, 700px, 0);
    transform: translate3d(0, 700px, 0);
    opacity: 0;
  }
}

In looking at my sample fiddle compared to the defined keyframes it only seems to transition to each position once rather than moving back and forth as I would expect, and as it does in on the animate.css page.

I have also verified that I am adding the same classes as the working page, and adding it in js. I've also copied the styles from the animate.css homepage and verified I had the same js dependencies, to see if that would make a difference none of these have helped.

Summary

What could cause a CSS animation to not progress correctly through all of it's key frames, and what would make this specific hinge animation, perform differently from one page to another as seen in my fiddle example?

Edit

I've tested a few more thoughts. @Cbroe brought up a question about jquery's document.ready behavior, and suggested using window.load instead to test. I also wanted to see if it was linked to jsfiddles, built in External Resource management. To test, I ported the code to this jsbin and pulled in the cdn reference explicitly. I got the same behavior with the new setup as the old.

like image 639
Mabdullah Avatar asked Nov 10 '22 04:11

Mabdullah


1 Answers

There is something wrong with the minified version of animate.css.

I changed:

<link rel="stylesheet" type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.0/animate.min.css">

To:

<link rel="stylesheet" type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.0/animate.css">

And it worked in Chrome and Safari. Strange. Must be something up with the minifier?

http://jsbin.com/luvixoxu/1/edit


Couple of side notes. You don't need to use CDATA in your Javascript anymore. That was for browsers that didn't recognize script tags many years ago; thankfully we are way past that. Technically, you don't even need 'type="text/javascript"' with HTML5 as it is the default.

You may not need jQuery for the delay; CSS animations have a delay option. Whenever possible avoid setTimeouts.

http://jsbin.com/pumigeqo/1/edit

Don't use $(window).load(); this will only trigger when the entire page (including images) has loaded. You do not need a onload function, simply place the script tags immediately before the closing body. The CSS in the head will load before the HTML, the HTML will load, and then Javascript will fire. I'd also recommend moving jQuery to immediate above the inline script otherwise it will delay the page load.

like image 90
Jason Avatar answered Nov 12 '22 17:11

Jason