Loading spinners are lots of fun. Their main purpose is to let users know that the app is loading, but it has a secondary one that make them very special: they should amuse the users while they are waiting. If they are good, they even make the waiting time shorter. The spinner is probably the part of an application where the designer can be more creative, having the freedom for creating a funny animation in an environment traditionally marked by the static nature of most of the components.
My challenge is to create 10 different loading spinners using 4 circles and CSS3 animations to cheer them up. It is a good creativity exercise, that will make me explore some key parts of CSS3 animations and, what is better, show them to you. I hope they are inspiring, let's start!
1. Newton's cradle
See the Pen Newton's cradle by Javier Marquez (@arqex) on CodePen.
Hey! That doesn't spin, it is not a spinner! Well, it is common among loading animations to be circular, but I will start with some plain ones because they are simpler.I will use the --prefix-free
option offered by codepen in all the spinners, so the result CSS will be much easier to read.
In the Newton's cradle only two balls are animated. I get a natural movement updating the animation-timing-function
inside a keyframe. animation-timing-function
applies easing to every transition between keyframes. When the function is updated inside some keyframe, the transition to the following one will use that given function. Using ease-out
when the ball is going away and ease-in
when it is returning we have the desired pendulum effect.
2. Wave
See the Pen Wave by Javier Marquez (@arqex) on CodePen.
The timing function update inside a keyframe is also used in this spinner to ease the ball jump. Timings functions are really powerful, and for the wiping ball I am using a customizedcubic-bezier
value.
I expected the ease
value to work here, but it was producing collisions with the jumping balls. That's because the ease
value doesn't apply the same easing for the beginning than for the end of the animation, so I had to use cubic-bezier
to get the effect I want. I would explain cubic-bezier
curves here, but the easiest way to understand how they work is visiting cubic-bezier.com, its interactive graph is worth a thousand words.
3. Circus
See the Pen Circus by Javier Marquez (@arqex) on CodePen.
Here we are spinning. Well, sort of... I will only use 2D transformations to create my spinners, so here there are just moving and scaling.I use two animations for every ball. When you apply more than one animation to the same element, all of them run at the same time and , unfortunatelly, there is no way to create a queue using CSS3. But in this case is good enough.
Circus uses negative animation-delay
values to set the starting position and size of each ball, and make them spin from the begining. As you can see, CSS3 transforms are used to change the size and position of the balls. Transform are really handy for CSS3 animations, I like especially the scale
one, that makes the balls grow or shrink respecting the center of the elements. That means the balls grow/shrink to the same proportion to the left/right horizontally and to the top/bottom vertically. If I had used width
and height
properties, the balls just would have grown/shrunk to the left and the bottom. By default, the origin of CSS3 transformation is the center of the element.
4. Atom
See the Pen Atom by Javier Marquez (@arqex) on CodePen.
Let's start creating animations less horizontal. I will use Circu's 3D effect to create some electrons spinning around a nucleus :)Here the .ball
elements are actually squares, and the circles that are shown are :before
pseudo-elements positioned absolutely at the top left of the square. Every square is rotated to make the balls move with a different inclination. Try to uncomment the background
property in the electron mixin to see what I mean.
Animating the z-index
property in the ball containers, I could make the electrons go back and forth around the nucleus. Pay attention than in firefox, to animate z-index
property, the element should have a z-index
value set up, otherwise it won't work. Also the nucleus has a subtle scale animation that make the spinner feel more dynamic.
People from github, don't you like it for you atom editor? :)
5. Fussion
See the Pen Fussion by Javier Marquez (@arqex) on CodePen.
So far whe have animated the position and the size of the balls, but focusing in other properties we can get really different spinners. Fussion focus in background colors, and it is inspired by my of Nexus 7's boot animation.It is a basic strategy for every spinner to render the balls in the same state that they had in the begining of the loop, in order to make possible repeat the animation infinitely. In this case, every ball is transformed in the next one to get ready for the next loop. Making the balls semi-transparent creates the effect of color fussion when they are all together.
6. Mitosis
See the Pen Mitosis by Javier Marquez (@arqex) on CodePen.
Mitosis uses analternate
value for the animation-direction
property, that means that when the animation finishes, goes backwards to the begining again. That way the balls can split at the begining and merge at the end coding just the half of the animation.
But, if you look at the animation the balls are not merged in the same direction than they were splitted, that's because the whole spinner is rotated 90 degrees in the middle of the loop, using the step(2, end)
value for the animation-timing-function
. The step function make the animations complete rendering just the number of frames given to the function. In our case 2 frames, the first is rotated 0 degrees and the second 90. The end of the animation (a 180º rotation) is never visible because a new loop starts again.
Another trick used in Mitosis is the deformation of the balls, they are scaled horizontally and vertically asynchronously, showing a really interesting jelly effect.
7. Flower
See the Pen Flower by Javier Marquez (@arqex) on CodePen.
First spinner here! Remember when I explained at Circus spinner that I said that by default the CSS3 transformations have the center of the object as origin by default? In flower, all the transformation's origins for the balls have been moved to the center of the spinner. That way the balls use that point as the center of the rotation instead their own center, so they can rotate as if they were one circle.transform-origin
is the property that let us customize the center of all the transformations.
Thanks to LESS the calculation of the origin is a bit easier. In this spinner I wish I had some way of enqueueing the animations, because calculate the keyframes position manually was really painful.
8. Clock
See the Pen Clock by Javier Marquez (@arqex) on CodePen.
Sometimes, to make some element spin, it is not necessary to change thetransform-origin
. In this case, :before
pseudo-elements are used to render the balls, the same way they were in Atom spinner. So every .ball
element is really a square, and the ball is placed in its top left. Rotating those squares we can make all the balls spin using the same center.
The step
function is again used in the .spinner
element to create the effect of whole spinner rotation in every loop of the ball group.
9. Washing machine
See the Pen Washing machine by Javier Marquez (@arqex) on CodePen.
Here the borders are the starring of the spinner, but, in this case, none of the balls is animated. The whole spinner is what is rotated, very fast, and alternating the direction thanks to theanimation-direction
property.
In this spinner :before
pseudoelements are used for rendering the small balls, and the .ball
elements are rotated to place the balls in different points of the big border. Again, LESS is really helpful to make all the calculations needed to center the balls in their container.
10. Pulse
See the Pen Pulse by Javier Marquez (@arqex) on CodePen.
This is an example of how diverse spinners can be made if we focus in different css properties. The main property animated here isborder
, with a little help of the opacity
one to create a bubbling effect.
This is not a complex slider because every ball uses the same animation. Here again, animation-delay
is our friend to make every ball bubble at their time.
Conclusion
Here it is where I am supposed to say "Animations are awesome, come on! Use them!". They have very strong points:- No need of any external libraries.
- The animations are hardware accelerated, so their performance is really good.
Also, browser support is not really big. At the moment of writing this article, only 23.8% of users will be able to see the animations if you don't use vendor prefixes, according to Can I Use, so you will need a css prefixer if you don't want to get old writing them all.
A way of making a queue of animations would be great to have. Currently, CSS transitions can be used to create a queue, but you need a touch of javascript too coordinate when to apply them.
The last issue I would like to point out is that it is impossible to apply transformations independently. For example, if you want to move an element from 0px to 130px and, and in the middle you want to scale it to a 200% you need to calculate manually also the position of the element in that middle point:
@keyframes my-animation { 0%{ transform: translateX(0); } 50%{ transform: translateX(65px) scale(2,2); } 100%{ transform: translateX(130px); } }
It may seem not a big problem, but if you want to apply some easing function, it will be applied to the 50% keyframe too, so it will got slower/faster in the middle of the animation.
I wouldn't use any library just to create a spinner in my projects, but if I had to create an app with some complex animation I would really think about using some tool like velocity.js to make my life easier and gain some cross browser compatibility.