Skip to content

24 ways to impress your friends

Giving CSS Animations and Transitions Their Place

CSS animations and transitions may not sit squarely in the realm of the behaviour layer, but they’re stepping up into this area that used to be pure JavaScript territory. Heck, CSS might even perform better than its JavaScript equivalents in some cases. That’s pretty serious! With CSS’s new tricks blurring the lines between presentation and behaviour, it can start to feel bloated and messy in our CSS files. It’s an uncomfortable feeling.

Here are a pair of methods I’ve found to be pretty helpful in keeping the potential bloat and wire-crossing under control when CSS has its hands in both presentation and behaviour.

Same eggs, more baskets

Structuring your CSS to have separate files for layout, typography, grids, and so on is a fairly common approach these days. But which one do you put your transitions and animations in? The initial answer, as always, is “it depends”.

Small effects here and there will likely sit just fine with your other styles. When you move into more involved effects that require multiple animations and some logic support from JavaScript, it’s probably time to choose none of the above, and create a separate CSS file just for them.

Putting all your animations in one file is a huge help for code organization. Even if you opt for a name less literal than animations.css, you’ll know exactly where to go for anything CSS animation related. That saves time and effort when it comes to editing and maintenance. Keeping track of which animations are still currently used is easier when they’re all grouped together as well. And as an added bonus, you won’t have to look at all those horribly unattractive and repetitive prefixed @-keyframe rules unless you actually need to.

An animations.css file might look something like the snippet below. It defines each animation’s keyframes and defines a class for each variation of that animation you’ll be using. Depending on the situation, you may also want to include transitions here in a similar way. (I’ve found defining transitions as their own class, or mixin, to be a huge help in past projects for me.)

// defining the animation
@keyframes catFall {
 from { background-position: center 0;}
 to {background-position: center 1000px;}
@-webkit-keyframes catFall {
 from { background-position: center 0;}
 to {background-position: center 1000px;}
@-moz-keyframes catFall {
 from { background-position: center 0;}
 to {background-position: center 1000px;}
@-ms-keyframes catFall {
 from { background-position: center 0;}
 to {background-position: center 1000px;}


// class that assigns the animation

.catsBackground {
 height: 100%;
 background: transparent url(../endlessKittens.png) 0 0 repeat-y;
 animation: catFall 1s linear infinite;
 -webkit-animation: catFall 1s linear infinite;
 -moz-animation: catFall 1s linear infinite;
 -ms-animation: catFall 1s linear infinite;

If we don’t need it, why load it?

Having all those CSS animations and transitions in one file gives us the added flexibility to load them only when we want to. Loading a whole lot of things that will never be used might seem like a bit of a waste.

While CSS has us impressed with its motion chops, it falls flat when it comes to the logic and fine-grained control. JavaScript, on the other hand, is pretty good at both those things. Chances are the content of your animations.css file isn’t acting alone. You’ll likely be adding and removing classes via JavaScript to manage your CSS animations at the very least. If your CSS animations are so entwined with JavaScript, why not let them hang out with the rest of the behaviour layer and only come out to play when JavaScript is supported?

Dynamically linking your animations.css file like this means it will be completely ignored if JavaScript is off or not supported. No JavaScript? No additional behaviour, not even the parts handled by CSS.

document.write('<link rel="stylesheet" type="text/css" href="animations.css">');

This technique comes up in progressive enhancement techniques as well, but it can help here to keep your presentation and behaviour nicely separated when more than one language is involved. The aim in both cases is to avoid loading files we won’t be using.

If you happen to be doing something a bit fancier – like 3-D transforms or critical animations that require more nuanced fallbacks – you might need something like modernizr to step in to determine support more specifically. But the general idea is the same.

Summing it all up

Using a couple of simple techniques like these, we get to pick where to best draw the line between behaviour and presentation based on the situation at hand, not just on what language we’re using. The power of when to separate and how to reassemble the individual pieces can be even greater if you use preprocessors as part of your process. We’ve got a lot of options! The important part is to make forward-thinking choices to save your future self, and even your current self, unnecessary headaches.

About the author

Val Head is a web animation expert, author, and Design Evangelist at Adobe. She is the author of Designing Interface Animation, published by Rosenfeld Media, teaches CSS Animation on, and curates the weekly UI Animation Newsletter.

More articles by Val