A Short Intro Into CSS Animations
Do I even need to use animations on a website?
Short answer is YES. If you’re from 2023.
You see, people are evolutionarily trained to notice motions, our survival depended on it. Because of that, a well designed animation on a page can guide your users. It’s much more convenient for users’ eyes when they get information where it is expected to come from. So when you hover on a menu item the sub-menu should appear smoothly, because that’s what users expect to happen.
I guess we all tend to face those annoying pop ups when you try to leave a site. I don’t know if those things are good for SEO or site conversion, but appearing out of nowhere and absolutely immediately shatters the user’s experience big time.
Nowadays web animations are not only about showing some cool hover effect or smoothly displaying the user’s product cart from the side of the page. There’s such a type of page called “scrollytelling”, when a user just needs to keep scrolling the page and discover a story.
It can be anything — a historical excursion, a product presentation, a person’s CV. And it’s all possible because of web animations. Because I bet you won’t like to watch different elements just pop up on the page all of the sudden.
You can also use animations in other ways of data visualisation. You can filter and reorder products or other data, you are able to show changes over time (can be a part of scrollytelling as well).
OK, now that I hope you agree that it’s a good practice to use animations on your web pages, let’s dive deeper into web animation using CSS.
CSS animations
This comes “in a box” with every modern browser (mobile browsers as well). Well, technically it comes with CSS3, which is supported by modern browsers. CSS animations make it possible to transition between different states using a set of keyframes.
CSS animations become the most handy when you need to apply a simple transition between different element states. For example, to make a link change its colour smoothly on hover. All you need to do is to add a transition
property to your element. Actually it’s a shorthand property, which combines transition-property
, transition-duration
, transition-timing-function
, and transition-delay
properties.
So specify a property you want the transition to be applied to (or set to all if you want to apply transition effects to all properties that change). Provide transition’s delay if you need, transition’s duration and transition’s timing function. Voila, you have a smooth good-looking transition effect on your page.
A quick and simple example:
a {
color: blue; /* default link colour */
transition: color 300ms ease-in;
}
a:hover {
color: red; /* link colour on hover */
}
Here we set transition property to color (since we only want to apply transition on the colour of links), transition duration is equal 300ms (milliseconds), no delay. The timing function is an ease-in function (works like this: starts off slowly, with the transition speed increasing until complete).
Here’s how it will look:
But let’s make something more complex. In fact, let’s create an actual animation, not just a transition between properties. So you will have more control over the intermediate steps of the animation sequence than transitions.
The animation sequence in CSS3 is setted up by the @keyframes
rule. All you have to do is to provide keyframes and assign animation states to them. Take a look at the example below for better understanding.
@keyframes rotateSquare {
0% {
transform: rotate(0deg);
}
50% {
background-color: red;
}
100% {
transform: rotate(360deg);
}
}
So the keyframes are 0%, 50% and 100%. In human words the code above means: I want to set rotation of an element to 0 degrees at the start of animation (at 0% of animation duration). Then, when the animation reaches to its middle (50%) I want to change the background-color of the element to red, and at the end (100%) I want that element to make a full rotation of 360 degrees.
Now when we have the animation rule, we just need to apply that animation to the element we want to animate. That can be achieved by using the animation
property (has similar syntax to transition property):
.square {
width: 10rem;
height: 10rem;
background: blue;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
animation: rotateSquare 1000ms ease-in-out infinite;
}
Here’s the final result:
So the rotateSquare
is the name of the animation (can be provided by standalone property animation-name
), which was defined by @keyframes
rule earlier. 1000ms is the animation’s duration (animation-duration
standalone property). The timing function sets to ease-in (animation-timing-function
). The last property is animation-iteration-count
equals to infinite, which means our animation will be repeated infinite times (until the user refreshes the page or closes the tab of course).
There are more properties for CSS animations so you can better handle the whole sequence. You can familiarise yourself with them and get more examples at the MDN Web Docs.
Which properties should I use to animate with CSS?
The best practice is to use properties, which DO NOT trigger layout or paint steps on the rendering pipeline.
Long story short, to display something on a webpage the browser has to go through the following sequential steps:
- Style: Calculate the styles that apply to the elements.
- Layout: Generate the geometry and position for each element.
- Paint: Fill out the pixels for each element into layers.
- Composite: Draw the layers to the screen.
Since those steps are sequential, changing the element’s position (top
, left
, right
, bottom
) will trigger the layout step, which will force the rest of the steps (paint and composite).
The only properties that don’t trigger layout or paint steps are transform
and opacity
. Indeed, those properties do not affect an element’s position, meaning the browser doesn’t need to recalculate it and trigger the layout step.
This means you should try to use only transform and opacity CSS properties for animations. If you think that this is too limited, let me remind you, that the transform property can: translate (move), rotate, skew, scale and perspective by all axes any element.
But still you may need to animate colours and borders, and that’s fine too. Just don’t animate the most performance expensive properties, like width
, height
, top
, left
, right
, bottom
etc. Those will trigger the Layout step in the rendering pipeline and I bet you won’t be satisfied with the FPS you get.
Here’s an example of animations, which trigger Layout, Paint and Composite layers:
Use this cheat sheet if you not sure which property to use for animation via CSS:
One more feature I want to mention about CSS animations is their event hooks in JavaScript. You can listen when your animation starts, ends, iterates and aborts.
If we use the example above again, to detect when the square starts to animate use animationstart
event listener:
const square = document.querySelector(".square");
square.addEventListener("animationstart", () => {
console.log("Animation started");
});
For the animation ends state use animationend
event, when the animation ends and another iteration begins use animationiteration
event. And if the animation was aborted (e.g you hide the element using CSS) the animationcancel
event is fired.
To sum up, CSS animations are perfect for making elements interactive. And since CSS animations have native support they have quite a good performance, especially for non-complex easings. So if you need to highlight your links or buttons on hover, or maybe create a pulse preloader — use CSS animations. And if you don’t want to spend much time on inventing them — here are some good libraries you can include to your project and use CSS animations from there:
- Animate.css — one of the most popular CSS animations libraries with lots of cool-looking effects
- Hamburgers — to make those burgers collapse and restore elegantly
- Magic Effects — a set of simple animations to include in your project
- Loaders — a collection of awesome loaders
But are CSS animations so good indeed?
Well, as I said earlier, CSS animations are good for quite simple animations. If you have a complex scenario, when one animation should start after another, or with some delays — you’ll have a terrible headache calculating all those durations and delays in CSS animation.
That’s why for complicated animations I suggest switching to JavaScript based animations. I will describe them in more detail in the upcoming article.
But if you already wish to start animating with JS, you can examine Web Animations API and my favourite library GSAP.
If you find this article helpful — don’t hesitate to clap, subscribe and leave your thoughts in the comments 😊
Thanks for reading!
Stay safe and peace to you!