It used to be that designers designed and coders coded. There was no crossover, and that’s the way it was. But with the advent of CSS transitions and animations, those lines are blurring a bit. It’s no longer as simple as the designer dictating the design and the coder transcribing—designers must now know something about code, and coders must know something about design in order to effectively collaborate.
As an example, let’s say a designer asks a developer to make a box bounce. That’s it—no additional instruction. Without some cross-knowledge and a common vocabulary, both sides are a little lost in this communication: the developer doesn’t have enough information to fully realize the designer’s vision, but the designer doesn’t really know what the options are and how to communicate them. With a very basic interpretation, you might end up with something that looks like this:
See the Pen Bouncing Box 1 by Brandon Gregory (@pulpexploder) on CodePen.
Not very exciting. Although, to be fair, this does meet all of the criteria given. We can definitely do better than this, though.
The first thing to look at is the timing function. In the above example, we’re using a linear timing function, which means that the box is constantly moving at the same speed. In some cases, this is desirable; however, in the real world, motion usually doesn’t work like that.
An easy fix is to simply change the timing function to ease. This makes the beginning and ending of each animation a little slower than the middle part, which adds a more natural look to some animations. Here’s the box with the easing function turned on:
See the Pen Bouncing Box 2 by Brandon Gregory (@pulpexploder) on CodePen.
This is a slight improvement, but there’s still a lot of work to be done. The box still looks mechanical and stiff, with the same animation occurring in the same timeframe over and over. Adding a slight delay between bounces adds some visual contrast that seems a little more natural:
See the Pen Bouncing Box 3 by Brandon Gregory (@pulpexploder) on CodePen.
The box now looks like it’s jumping rather than simply moving up and down. There’s a little wind-up and cool-down between jumps that mimics what a live creature might do if given the same instruction. Even though we have no reference for what a jumping box would look like, we all have a pretty good idea of what a jumping creature would look like. Because we know what would happen in nature, by mimicking that, the animation feels more natural. But we can do more to make that wind-up feel a little more weighty.
If you watch cartoons, you’ll notice that natural movements are often exaggerated, creating a caricature of real life. When done well, this can feel just as natural as something in the real world, with the added bonus of infusing a little charm and character into the animation.
At this stage, collaboration between the designer and developer is crucial — but many designers may not even be aware that these options exist. It may be up to the developer to pitch this possibility to the designer.
By adding some subtle distortion to the scale of the box, we can add a lot to the animation:
See the Pen Bouncing Box 4 by Brandon Gregory (@pulpexploder) on CodePen.
Now, the box has character. It feels alive. There are many things to tweak, but this is already moving much farther than the original instruction — in a very good way!
We’re going to go a step further and add a little rebound at the end of the jump:
See the Pen Bouncing Box 5 by Brandon Gregory (@pulpexploder) on CodePen.
The second bounce is making this feel more alive, but something still seems off. The bounce looks stiff compared to the rest of the animation. We need to add another bit of distortion like we did for the wind-up:
See the Pen Bouncing Box 6 by Brandon Gregory (@pulpexploder) on CodePen.
That subtle distortion at the end makes the rebound seem much more natural. Overall, a huge improvement from our basic linear bounce in the first example.
That right there may be exactly what we’re looking for, but further tweaks to the rate of movement can be made with a custom cubic Bézier curve:
See the Pen Bouncing Box 7 by Brandon Gregory (@pulpexploder) on CodePen.
Without both the designer and the developer aware of basic animation principles and controls, this level of customization is impossible. Really, this article just scratches the surface of both fields. If you’re a web designer or a web developer who works with designers, I’d strongly urge you to read up on both.
For animation principles, The Illusion of Life: Disney Animation by Ollie Johnston and Frank Thomas is a great primer on how to make that caricature of real life seem alive and real. With that common language in place, communication and collaboration between designers and developers becomes much easier.
For the technical controls and variations of CSS animation, the possibilities are nearly endless. Delay and timing are simple to adjust. As mentioned, if you don’t like the out-of-the-box ease timing function, it’s very possible to create your own using a cubic-bezier()
. You can also adjust the level of distortion you want to bring the animation closer to or further from reality. The important thing is that both the designer and developer are thinking about these variations rather than blindly taking everything without customization. Shared knowledge and collaboration can make even simple animations into great ones.
More Resources
- 12 basic principles of animation – Wikipedia post outlining the concepts introduced in The Illusion of Life.
- The Guide to CSS Animation: Principles and Examples – Smashing Magazine article providing a comprehensive guide to CSS animations.
- Animation in Design Systems – 24 Ways article by Sarah Drasner
- Animation property – CSS-Tricks almanac entry covering the property and its values
- Transition property – CSS-Tricks almanac entry covering the property and its values
- CubicBezier.com – Resource to create custom animation curves with a user interface.
This is a important topic and I’m glad people like you are writing about it. But as a Coder and Designer by myself I’m not satisfied with the final result. It still feels not like a natural motion to me, you still have to improvise the timing function. As part of a 100 Days CSS Challenge I made a similar jumping box, you can look at it here: https://codepen.io/roydigerhund/pen/jqJvWK
Your example looks great
Holy s**t! Your example is awesome!
Matze, that’s awesome!
Awesome article. Something I’ve been keen to skill-up on, so thanks for writing it!
Great! Thanks for commenting!
Living things are squishy. So I’d like to add a bit of oblateness when the box jumps. The relevant keyframes are:
Nice! Here’s the pen I made to preview it:
The one thing that still feels unnatural about this is that the box’s descent slows down just before it reaches the bottom. For a real “bounce” feel, the box’s velocity should be greatest at the end of the drop. Otherwise, it’s like it’s putting on the “air brakes”.
Yeah I agree. That slowing down effect is really bugging me.
Honestly I’d just make the landing a mirror of the jump, i.e. make the box squish against the floor instead of bouncing off it. Bouncing on landing would imply the box is rigid, yet the jumping implies the exact opposite.
This is a little off topic, but I’m trying to create a flip effect for a matching game where when the cards are flip they stay in place for a few seconds so the child can memorize it before it flips back over. I have tried using the “easy in-out” with different time and it still fills back over to quickly. Can I add a pause?
The timing function is “ease-in-out” . . . maybe that’s the problem? Always the little things . . . :-)
Richard, for that, it would probably be best to use a keyframes animation rather than use a timing function, custom or otherwise. Something like this:
@keyframes cardFlip
{
0% { [base state] }
10% { [flipped state] }
90% { [flipped state] }
100% { [base state] }
}
That’s not production-ready code, of course, but it will hopefully get you on the right track.
Although it might be possible to do complex animations purely through css, it often isn’t worth going down a pure css route. It’s better to go with a js animation engine like GSAP.
JS animation engines give you much finer control over the animation and it is still very performant.
This is a site I built recently that has quite a few cool GSAP powered animations:
http://annualreport.communications.gov.au/2017
I made this old one using only CSS to run the animations (aside from a bit of js just adding and removing classes), it was an absolute nightmare to build though:
http://annualreport.communications.gov.au/2014
(Has to be viewed on Desktop to see the animations)
For simple animations, go with css. For complex animations it’s much better going with GSAP. You will still need to understand fundamental animation concepts like squash and stretch to make nice looking animations though.
I would always go first with CSS Animations and only if it is not possibly animate it by JS. CSS will perform better than a similar JS animation.
@Matze not necessarily, JS animations can actually have better performance than CSS in some circumstances.
GSAP wrote up an article pitting css & js against each other. (Granted GSAP are going to be biased but it comes across as objective and honest)
https://greensock.com/transitions
For simple transitions between two states, use css.
If it is a moderately complex animation and it is just a one off, try with just css.
If it is an incredibly complex animation or your site has moderately complex animations all over the place. Go straight for the JS solution.
Khan Academy has some free classes from Pixar that discuss animation and movement.
perfect!!
easy to read and very helpful, thanks :D
If we want to simulate gravity, the box should slow down as it reaches the top and then accelerate as it goes back down. I think the best way to simulate the gravity is to reverse the animation so the time 0% and 100% are when it is at the highest point. Using ease-in-out, it will be moving the slowest at the top and fastest at the bottom. Try something like the following keyframes
Nice article! Thanks! Found out recently that you can also play a lot with the animation-timing-function in the keyframes, to get more like an After Effects kind of set up https://codepen.io/boasthin/full/BJMWLq/