Managing CSS Animations In Sass

Most mixins, placeholders and other Sass tools out there do a great job of making animation easier to implement, but it may be more than we actually need.

The challenge of CSS animation has always been managing them on bigger sites and applying consistent, but custom results depending on what you want to achieve. That’s where Sass comes in. Here’s a few examples of mixins or tools I’ve tried in the past:

Animation possibilities with Sass

Sass versions of Animate.css

Animate.css by Dan Eden is a great cross-browser library of predefined vanilla CSS animations. It allows you to add a class such as bounceInUp to an element to get that desired effect. Thanks to Geoff Graham and Tom Gillard, there are a couple of Sass versions of this library, here and here respectively. The Sass tools will allow you to override base settings and utilize mixins throughout your Sass framework.

These libraries are useful and serve their purpose to help save time, especially on crunch projects where the key is to provide as much flexibility with animations as possible. However, the potential danger is as soon as you settle on only one or two variables much of the library becomes redundant; and you’re left with bloated CSS.

Compass, Bourbon & beyond

If you happen to use mixin libraries such as Compass or Bourbon, you’ll know that they provide pretty useful tools and examples in terms of applying a mixin on any given element. In Bourbon, for example:

@include animation(scale 1.0s ease-in, slide 2.0s ease);

The above will output all the vendor prefixes and animation variables:

-webkit-animation-name: scale, slide;
-moz-animation-name: scale, slide;
animation-name: scale, slide;
-webkit-animation-duration: 2s;
-moz-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-timing-function: ease;
-moz-animation-timing-function: ease;
animation-timing-function: ease;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
animation-iteration-count: infinite;

Certainly useful and the code behind this is easy to achieve in 40 lines of code. It doesn’t provide the answer to manage your animations or transitions, but regardless of what system you have this will always be a go-to mixin.

Setting up variables

One method I’ve used before is to create a partial, such as _timing.scss, which is dedicated to all easing possibilities by using variables and cubic-bezier timing functions:

$ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530);
$ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190);
$ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715);
$ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035);
$ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335);

// Plus maybe 50 more...

Pretty handy, but ultimately I’m not going to need every single easing type. Granted it will only output the easing of choice in the CSS, but being a minimalist freak I have the tendency to want to keep my Sass structure as clean and minimal as possible so revisiting a project 6 months later won’t involve scratching my head.

Keeping it simple

There are a ton of other tools out there which I haven’t tried, and while there is a great temptation to throw in the towel and use one or create a complex one myself, it has occurred to me on previous projects that they can seem like overkill.

Lately I’ve been using a method that is really simple; more a way of thinking rather than an actual tool. Basically, I start by deciding on the animations I want even as far back as the creative. Less is definitely more, and most of the time I’ll settle on simple fades and slide ins. Keeping it all in my main settings partial, I’ll set up some predefined variables for both easing and speed.

Easing

I find that to keep animations consistent across the whole site, I’ll stick to one “special” easing type which will get used on any moving element. Applying custom easing to fades generally produces unnatural results, so I usually stick to linear for those.

When it comes to deciding on the special easing, it will depend on the context, but there are plenty of cheat sheet tools that will provide the desired cubic-bezier values, such as Easings.net and Ceaser.

So in my _settings.scss, I’ll have:

$easing_special: cubic-bezier(0.950,  0.050, 0.795, 0.035);

Speed

Next is the speed — which requires a little bit of thought depending on your layout and what you wish to achieve. The beauty of this will be the customization that you can apply to make the web site feel more seamless and consistent.

I’ll divide the web site layout up into “speed groups”. It can be grouped by specific components, but may also include general transform types such as fade, or utility type variables such as a text reveal. So that may typically look like:

$speed_colorchange: 0.2s;
$speed_navigation: 0.4s;
$speed_card: 0.5s;
$speed_slide: 0.7s;
$speed_fade: 1s;
$speed_textreveal: 1.5s;

Prior to this method, I was using a set of named variables to denote the speed — slow, medium, fast, very fast etc. The issue I run into was it would quickly get messy and hard to keep to track of. While I could easily alter the scale and balance of speeds in one place, it had no bearing or consistency. I would have to dive into specific partials and alter speeds to make elements pair better together. With these speed group variables, I can apply specific speeds to an entire component or transform type for example, making it consistent, seamless, and easy to modify.

Usage

With the special easing and speed variables in place, I can now apply them to an element:

transition: opacity $speed_fade,
transform $speed_slide $easing_special;

Simple right? Combine this with a mixin or Gulp task that outputs all your vendor prefixes, and you have yourself a solid yet simple method for managing your animations.

By Christian Miller  |  Follow me on Twitter