# Animations - [Technology choices](#technology-choices) - [Animation on element creation](#animation-on-element-creation) - [Animation on element removal](#animation-on-element-removal) - [Performance](#performance) --- ### Technology choices Animations are often used to make applications come alive. Nowadays, browsers have good support for CSS animations, and there are [various](https://greensock.com/gsap) [libraries](http://velocityjs.org/) that provide fast Javascript-based animations. There's also an upcoming [Web API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API) and a [polyfill](https://github.com/web-animations/web-animations-js) if you like living on the bleeding edge. Mithril does not provide any animation APIs per se, since these other options are more than sufficient to achieve rich, complex animations. Mithril does, however, offer hooks to make life easier in some specific cases where it's traditionally difficult to make animations work. --- ### Animation on element creation Animating an element via CSS when the element created couldn't be simpler. Just add an animation to a CSS class normally: ```css .fancy {animation:fade-in 0.5s;} @keyframes fade-in { from {opacity:0;} to {opacity:1;} } ``` ```javascript var FancyComponent = { view: function() { return m(".fancy", "Hello world") } } m.mount(document.body, FancyComponent) ``` --- ### Animation on element removal The problem with animating before removing an element is that we must wait until the animation is complete before we can actually remove the element. Fortunately, Mithril offers a [`onbeforeremove`](lifecycle-methods.md#onbeforeremove) hook that allows us to defer the removal of an element. Let's create an `exit` animation that fades `opacity` from 1 to 0. ```css .exit {animation:fade-out 0.5s;} @keyframes fade-out { from {opacity:1;} to {opacity:0;} } ``` Now let's create a contrived component that shows and hides the `FancyComponent` we created in the previous section: ```javascript var on = true var Toggler = { view: function() { return [ m("button", {onclick: function() {on = !on}}, "Toggle"), on ? m(FancyComponent) : null, ] } } ``` Next, let's modify `FancyComponent` so that it fades out when removed: ```javascript var FancyComponent = { onbeforeremove: function(vnode) { vnode.dom.classList.add("exit") return new Promise(function(resolve) { setTimeout(resolve, 500) }) }, view: function() { return m(".fancy", "Hello world") } } ``` `vnode.dom` points to the root DOM element of the component (`