Cool CSS Animation
Discover just how much you can do with CSS animation by learning to code cool, abstract effects with CSS.
CSS Animation Examples
CSS animation is powerful. When combined with the power of Sass loops, you can create really interesting animations with a few lines of code. The examples below represent a small range of what you can do with CSS animation.
By using basic CSS transforms, such as scale and rotate, with animation delays, the keyframe animations really come to life.
See the Pen Planar Shuffle by Miriam Nadler (@mknadler) on CodePen.
See the Pen Deep Rings by Miriam Nadler (@mknadler) on CodePen.
See the Pen Möbius 6hedrons (pure CSS) by Ana Tudor (@thebabydino) on CodePen.
See the Pen trickling cubes (pure CSS 3D) by Ana Tudor (@thebabydino) on CodePen.
See the Pen Shuffling Squares by Nick Ciliak (@nickcil) on CodePen.
See the Pen Four Corners by Nick Ciliak (@nickcil) on CodePen.
See the Pen Hypnotized by Nick Ciliak (@nickcil) on CodePen.
How to code cool CSS animations
This tutorial is an introduction to coding cool CSS animations using HTML and CSS. It's meant for those who already have a good understanding of HTML and CSS, with some familiarity with Sass.
From what I've found, the most challenging part isn't understanding the code but rather learning how to experiment. That's why it is important to have real-time visual feedback when coding a CSS animation. I prefer to use a browser-based editor that refreshes automatically as I code. (I recommend CodePen!)
Using CSS keyframes, animation delays, and CSS transforms, we'll create a simple yet interesting CSS animation. Let's get started!
Create an HTML element to animate
Start with a single element. This will form the basis of the CSS animation. To make it easier to manage the animation as a whole, create a wrapper element and set position: absolute
on the elements inside.
/* Sass */
.circle {
position: absolute;
width: 20px;
height: 20px;
border-radius: 100%;
background-color: turquoise;
}
<!-- HTML -->
<div class="animation-wrapper">
<div class="circle"></div>
</div>
Repeat the element to create a pattern
Duplicate the element, then use a Sass loop to space them out. Each can be targeted using the :nth-child selector.
To spread the elements out, I’m setting the left
property instead of transform: translate()
because the transform property will be set as part of the animation later and I don't want to overwrite it.
/* Sass */
.circle {
position: absolute;
width: 20px;
height: 20px;
border-radius: 100%;
background-color: turquoise;
}
@for $num from 1 through 8 {
.circle:nth-child(#{$num}) {
left: ($num - 1) * 30px;
}
}
<!-- HTML -->
<div class="animation-wrapper">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
Add motion using CSS keyframes
Keep it simple here. I've found the best way to start adding motion is to create keyframes and animation the transform
property. In this example, I'm animating transform: translate()
. For the keyframes, I start by keeping it to one or two steps and adding more in later.
/* Sass */
.circle {
position: absolute;
width: 20px;
height: 20px;
border-radius: 100%;
background-color: turquoise;
animation: move-the-circle 1s infinite;
transform-origin: center center;
}
@for $num from 1 through 8 {
.circle:nth-child(#{$num}) {
left: ($num - 1) * 30px;
}
}
@keyframes move-the-circle {
0% {
transform: translate(0, 0);
}
50% {
transform: translate(0, 50px);
}
100% {
transform: translate(0, 0);
}
}
<!-- HTML -->
<div class="animation-wrapper">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
Stagger the motion using CSS animation delay
Using the same Sass loop as before, set the animation-delay
property to be slightly offset for each element. This instantly makes the CSS animation dramatically more interesting.
/* Sass */
.circle {
position: absolute;
width: 20px;
height: 20px;
border-radius: 100%;
background-color: turquoise;
animation: move-the-circle 1s infinite;
transform-origin: center center;
}
@for $num from 1 through 8 {
.circle:nth-child(#{$num}) {
left: ($num - 1) * 30px;
animation-delay: $num * .1s;
}
}
@keyframes move-the-circle {
0% {
transform: translate(0, 0);
}
50% {
transform: translate(0, 50px);
}
100% {
transform: translate(0, 0);
}
}
<!-- HTML -->
<div class="animation-wrapper">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
Experiment with different values and properties
This is where the fun comes in! In the @keyframes
block, what happens when you change the background-color
, opacity
, and scale()
of the element? By experimenting with different values and properties, you can create many variations using the same basic setup. Try adding in more keyframe steps, adjusting the timing, and changing values until you create something cool and new.
/* Sass */
.circle {
position: absolute;
width: 20px;
height: 20px;
border-radius: 100%;
background-color: turquoise;
animation: move-the-circle 1s infinite;
transform-origin: center center;
}
@for $num from 1 through 8 {
.circle:nth-child(#{$num}) {
left: ($num - 1) * 30px;
animation-delay: $num * .1s;
}
}
@keyframes move-the-circle {
0% {
transform: translate(0, 0) scale(1);
opacity: 1;
background-color: turquoise;
}
50% {
transform: translate(0, 50px) scale(.4);
opacity: .5;
background-color: blue;
}
100% {
transform: translate(0, 0) scale(1);
opacity: 1;
background-color: turquoise;
}
}
<!-- HTML -->
<div class="animation-wrapper">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
Try it out!
It's easy to get started creating cool CSS animations with our CSS animation generator. Try it out and see what you can create!
CSS Animation Snippets
There's no need to start from scratch when creating your CSS animation. Use the CSS animation, keyframes, easing, and Sass loop code snippets below to get started.
CSS Animation Basics
Easy Animation Shorthand
.class {
animation: my-animation 1s ease infinite;
}
End animation on last frame
.class {
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
Keyframes Block
@keyframes my-animation {
0% {
transform: translate(0, 0);
}
50% {
transform: translate(0, 0);
}
100% {
transform: translate(0, 0);
}
}
CSS Animation Easing & Timing
Easing with keyword
.class {
animation-timing-function: ease-in;
}
Easing with bezier function
.class {
animation-timing-function: cubic-bezier(.44,.24,.83,.67);
}
Bounce easing
.class {
animation-timing-function: cubic-bezier(.4,1.21,.83,1.16);
}
Sass Loops for CSS Animation
Sass Loop (Delay)
$total: 10;
$delay: .1s;
@for $n from 1 through $total {
.element:nth-child(#{$n}) {
animation-delay: $n * $delay;
}
}
Random Number Function
@function randomNum($min, $max) {
$rand: random();
$randomNum: $min + floor($rand * (($max - $min) + 1));
@return $randomNum;
}
Sass Loop (Keyframes)
$total: 10;
$delay: .1s;
$duration: 2s;
@for $n from 1 through $total {
.element:nth-child(#{$n}) {
animation: my-animation-#{$n} $duration ease-out infinite;
}
@keyframes my-animation-#{$n} {
0% {
transform: translate(0, 0);
}
50% {
transform: translate($n * 10px, 0);
}
100% {
transform: translate(0, 0);
}
}
}