Search code examples
csscss-transitionseasing-functions

Specify a custom timing function for CSS transitions?


I use CSS transitions pretty frequently now but find it limiting to only have access to ease-in, ease-out etc.

The bezier-curve option appears to allow the most control but even this does not allow you to specify an actual easing equation that would simulate elastic easing etc..

Is there another option or does one need to resort to javascript to perform this type of animation?


Solution

  • I found there is no way to do an elastic transition with pure CSS. However you can cheat and do a CSS animation. This is what apple uses on their site:

    @-webkit-keyframes open-1 {
        from { opacity:0; -webkit-transform:translate3d( 210px, -145px, 0); }
        25%  { opacity:1; -webkit-transform:translate3d( -15.6px, 4.1px, 0); }
        30%  { opacity:1; -webkit-transform:translate3d( -10.3px, 2.7px, 0); }
        35%  { opacity:1; -webkit-transform:translate3d( 0, 0, 0); }
        40%  { opacity:1; -webkit-transform:translate3d( 4.5px, -1.2px, 0); }
        45%  { opacity:1; -webkit-transform:translate3d( 2.9px, -0.8px, 0); }
        50%  { opacity:1; -webkit-transform:translate3d( 0, 0, 0); }
        55%  { opacity:1; -webkit-transform:translate3d( -1.3px, 0.3px, 0); }
        60%  { opacity:1; -webkit-transform:translate3d( -0.8px, 0.2px, 0); }
        65%  { opacity:1; -webkit-transform:translate3d( 0, 0, 0); }
        70%  { opacity:1; -webkit-transform:translate3d( 0.4px, -0.1px, 0); }
        75%  { opacity:1; -webkit-transform:translate3d( 0.2px, -0.1px, 0); }
        80%  { opacity:1; -webkit-transform:translate3d( 0, 0, 0); }
        85%  { opacity:1; -webkit-transform:translate3d( -0.1px, 0, 0); }
        90%  { opacity:1; -webkit-transform:translate3d( -0.1px, 0, 0); }
        to   { opacity:1; -webkit-transform:translate3d( 0, 0, 0); }
    }
    

    These animations are used to great extent on Apple's own website: http://www.apple.com/mac/

    Obviously this is powerful to some extent -- since the animations are percentages you can easily change he duration and retain the effect.

    However, this is still very static. Let's say you want to click a button and have it perform an elastic scaling animation. No problem, one animation can be used over and over again for each button. But let's say you want to have an element elastically snap it's position to wherever the user most recently clicked or tapped on the screen. Well in this case you'd need to dynamically recalculate the keyframes and then apply the animation to the element.

    At the time of this writing I don't know that there are any good examples of dynamically generating CSS animations on the fly inside of javascript. In fact it probably warrants another question. All in all this is the only pure CSS way I found to do render a complex easing equation such as elastic easing purely with CSS.