Last article played with CSS animations to transition smoothly when making an element disapear. The follow up was pretty easy to find: let’s see how to animate the apparition of an element on the page!
Note: As for the previous article, the article focus on the code manipulating the CSS animation. Don’t forget to make sure the element appears correctly on the page in browsers that do not support CSS animations 🙂
When the dimensions of the inserted element are set in CSS, things are pretty simple. The starting point is clear (often a
animation. Easy, peasy!
For elements sized according to their content, I think you’ll have guessed the issue: how to measure the element's final size (and/or position) while it's not yet displayed, as the CSS animation needs this information to animate properly (medreams of animation working with
auto values :p)?
One strategy to overcome this problem is to create a hidden clone of the container the element is inserted in, with the same dimensions as the one already on the page. It needs:
- to be hidden using
visibility: hiddenrather than
display: noneso the layout gets computed
- to be out of the flow, so it does not leave a massive blank space on the screen.
position: absolutemakes a fine candidate for this.
With the clone in the DOM all that’s left is to insert the element in the clone, measure whatever is needed for the animation, generate the appropriate keyframes and trigger the animation.
Let's see how this looks with a list of items:
There are a few things to keep in mind when using this method:
- how cloning is done: Node.cloneNode() is the simplest way of cloning the container. However, the container might be the parent of a complex DOM structure you might not want to clone entirely everytime an element is added. Creating placeholders of the container’s children could make things simpler there. All that’s needed to measure the new element is the container and its child sizes, position and display properties.
- how the element is inserted in the clone: depending on how your container and its children are styled, you might not need to insert the element the same exact way it would be inserted in the document. A simple Node.appendChild can do the trick (like in the example).
- what to measure: obviously, you’ll want the dimensions (and maybe the position) of the inserted element. The insertion of and element will also shift its siblings around. Sometimes, the animation of the new element will also smoothly shift the siblings. But you might need to measure the new siblings positions and sizes and create them custom animations… if you want to animate them, of course!
Wrapping it up