Hiding elements and CSS animations

Following the last article about CSS animations using Javascript, let's see how we can apply this to something closer to a real life situation than a bouncing ball. Animating the disapearance of an element in a list, for example. Something to make the situation below a bit smoother:

At the moment, the element removal is pretty abrupt: click the button, boom it's just gone. Simply removing an element from the DOM does not bring the smoothest visual experience. Let's bring in some CSS animations to make things a bit more pleasant.

Note: The code in this article focuses on what happens when CSS animations are available. For a production website, you'd need to detect if they are available (using Modernizr, for example), and choose what to do if they aren't to make sure the element still gets removed.

Making elements disapear in CSS

If you think of hiding elements with CSS, display: none; is probably that first comes to your mind. Unfortunately, the values taken by the display property are not of a type that can be animated.

The next option in mind would be visibility: hidden;, but it has the same "I-am-not-animatable" issue.

Looking at the properties that are animatable, there are a few interesting options to make an element smoothly disapear, with these two probably being the most interesting:

  • opacity: to fade the element out
  • transform: to scale the element or translate it out of screen

Get it out of the way

Let's go with the transform property to make the removed element disapear to the right of the screen. The animation does not depend on dynamic values, so its keyframes can sit quitely in a stylesheet. It'll get triggered by adding the removed class to the element that's disapearing. The removed class also bears the animation-fill-mode: forwards; property to make sure the element keeps the styles at the end of the animation. Without it, the element would instantly got back to where it was at the start of the animation... not really what we want.

The translation works well. Click, and off the screen is the removed element! Unfortunately, it leaves a massive blank space where the element was. transform We still need to remove the element once it's out of the screen. CSS animations trigger a animationend event once they complete, so we'll use it to detect when to remove the element.

The element now slides out of the screen before it gets removed. Better! But the list still collapses quite abruptly once the element is removed. Let's improve that.

Note: Removing the element makes the animation-fill-mode property redundant. No risk for the element to revert to its initial style, it's not there anymore.

Collapsing smoothly

This time, we'll animate the height property to reclaim the vertical space previously occupied by the object.

Sounds simple, but the fact that height does not animate if its value is auto makes things a bit tricky. For height to be animatable, it needs both its start value and end value to be a specific length.

This means we'll need to measure the item and set its height before we trigger the animation. And as we want the element to collapse only at a certain point in the animation, we'll need to generate the keyframes with Javascript to maintain the height constant during the first part of the animation.

The first keyframe sets the initial height of the element to the one measured. Without it, the blank space will just snap instantly rather than smoothly collapsing. At the other end of the keyframes, we need to make sure the element is kept outside of the screen, which means repeating the transform in the last keyframe. And here we are, the element nicely moves out of the screen.

Note: Measuring the height of the removed element might impact the performances of your application (if you do it on to many of elements at the same time, for example, but probably not the only example). If it happens, animating max-height is a way to avoid measuring your elements. It might introduce a different perceived speed in the animations if your elements height are really different one from another, though.

Wrapping it up!

Despite not being able to animate display: none; or visiblity: hidden;, CSS animations are a great help when you want to make the removal of an element nicer to the eye. Especially if you need complex animations that could not be handled by CSS transitions on their own. No reason to have blinky disapearances anymore :)

comments powered by Disqus