“the way is long if one follows precepts, but short and helpful, if one follows patterns” ― Lucius Annaeus Seneca
I’ve had a lot of fun making a certain style of CSS animation demos on CodePen lately, all of which seem to follow a similar design pattern. Below are a couple of examples (embedded here as .gifs, but click through to see the live HTML/CSS versions):
I don’t know whether a legitimate use case exists for animations like these, and that’s 100% okay by me. Exploring your creative side and stretching the limits of what you can do with HTML, CSS, Sass, Javascript, canvas, SVG, etc. has plenty of value in itself. Plus I find it relaxing, almost soothing sometimes, to spend a little time experimenting and playing around with no specific end goal driving the process.
A note on CodePen
From the About CodePen page: “CodePen is a playground for the front end side of the web. It’s all about inspiration, education, and sharing.”
CodePen really lowers the barrier to entry for exploring front-end techniques, and makes it pretty frictionless to just try things out. With the click of a checkbox you can enable “prefix-free” mode, freeing you to write standard unprefixed CSS properties, and CodePen inserts all the necessary vendor prefixes (e.g. -moz
, -webkit
, etc) for you. The toggle of a button switches you from HTML to HAML, another button switches you from CSS to Sass, or SCSS, or LESS, and so on. It’s perfect for painless experimentation, so if you’ve never used it you should go try it out right now!
Here’s the trick
There’s a simple pattern I followed with all of the above examples. It’s basically this:
- Generate X number of elements with HAML
- Apply some basic styling to all of those elements
- Create a loop in Sass
- Inside of the loop, use the
:nth-child
or:nth-of-type
pseudo selector to create a slightly different style for each element. That often means a different color, a differenttransform
property, a different keyframe animation, or in some cases the same animation but a differentanimation-delay
for each element - Then all that’s left is just to play around with different transforms and animation properties, to see what looks cool or interesting
Diving in to the markup: 1 minute

Let’s build an example project using this pattern. The first thing you will want to do is generate some number of html elements to work with. For this example, let’s make 100 div
s, just because 100 is a nice round number, not too big and not too small, and the div
is the go-to generic block element. I’m going to use HAML for this because it’s nice and quick, but there’s no reason you just couldn’t type in <div></div>
a hundred times if that’s more your style. To use HAML in the real world you have to install Ruby, then install HAML as a ruby gem, then I don’t know what else… in CodePen to use HAML you just click the little gear icon at the top left of the HTML panel, then click the big button that says HAML. Then insert the two lines below, and that’s your 100 div
s.
[ruby]
-(1..100).each do
%div
[/ruby]
Technically that’s a block of Ruby, and it creates a “range” from 1-100, and then iterates through each
number in the range, creating a div
for each one. But do you need to know Ruby or HAML to do this? I don’t! As long as you can use the snippet above you’re golden for now. Here’s a quick little intro to HAML if you want to learn more about that.
Applying some basic styles: 1.5 minutes
Okay so I allotted 90 seconds for this step, but once you’ve done it a time or two you could probably type it in 45 seconds :)
[css]
body{
background: #111;
}
div{
height: 20px;
width: 20px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -10px;
margin-left: -10px;
border-radius: 3px;
}
[/css]
What’s happening here is we’re making the div
s into 20px square blocks, then positioning them all absolutely in the exact middle of the screen using this old technique. Because they are all absolutely positioned, they will all be stacked up one atop the other like a deck of cards.
The basic Sass loop: 2 minutes

Now you’re going to want to turn on Sass, using the .scss syntax, using the same “click the gear” method that we used to turn on HAML. Go ahead and click “Reset” and “Prefix free” while you’re in there, it’ll make writing animations and transforms much quicker in a minute here :)
Once you’ve got that done, we’ll use the code below to create a @for
loop in Sass. Here’s a crash course in Sass control directives, if you really must know more (and eventually you will want to), but all you need for this is the code below. The $i
is the iterator variable, and the loop will go from 1 through 100, and $i will increment each time (the first time through $i = 1, then $i = 2, then $i = 3, and so on).
Inside of the @for
loop, we use the :nth-of-type
pseudo-class with $i
passed in as the argument.
[css]
@for $i from 1 through 100{
div:nth-of-type(#{$i}){
/* interesting stuff goes here */
}
}
[/css]
When the Sass is compiled (or transpiled) to CSS, it’ll look like this:
[css]
div:nth-of-type(1}){
/* interesting stuff goes here */
}
div:nth-of-type(2){
/* interesting stuff goes here */
}
div:nth-of-type(3){
/* interesting stuff goes here */
}
… and so on …
[/css]
The interesting parts: 5.5 minutes
This is where you’ll spend the most time playing with options and tweaking numbers. By this point you’ve got the entire necessary structure in place, but what you put inside the Sass @for
loop will determine how the final product will look and behave. Here’s the code for an example project, take a look and I’ll walk through it line-by-line below.
[css]
@for $i from 1 through 100{
div:nth-of-type(#{$i}){
background: hsla($i*3.6, 90, 50, .8);
animation: shift#{$i} 35s $i*.3+s linear infinite;
}
@keyframes shift#{$i}{
10%{
opacity: 0;
}
20%{
transform:rotate($i*60+deg) translateX($i*5+px) translateY($i*5+px) scale(2);
opacity: 0;
}
}
}
[/css]
Lines 1 and 2 were discussed above, then on line 3 we’ll set a background color for each div
. I really like using the HSLA (Hue, Saturation, Lightness, Alpha) color notation here because it’s incredibly easy to manipulate programmatically, including iterating through the entire rainbow. While the saturation and lightness arguments take a number from 1 to 100, and the alpha takes a value between 0 and 1, the hue argument takes a number between 0 and 360 (like degrees on a color wheel), and values above and below will be modulus 360, so you can pass any number in for hue and it’ll produce a color.
Remember that $i
is going to be 1 for the first div
, 2 for the second div
, 3 for the third div
, and so on, and that we have 100 div
s. By multiplying $i
by 3.6 we get full coverage of all the hues of the color spectrum, from 0 to 360 (or really from 3.6 to 363.6, but close enough for me).
Now for the last part, you’re going to want to have a decent grasp on CSS keyframe animations. On line 4 where we specify the animation, we are first giving it a name using shift#{$i}
. So we are giving each div its own unique animation, called shift1, shift2, shift3, etc. Then we define a duration of 35 seconds, a delay of $i*.3
so that each div’s animation starts at a different time (.3 seconds, .6 seconds, .9 seconds, etc), an easing function of linear
and an iteration-count of infinite
.
Starting on line 6 we are defining 100 different keyframe animations, each slightly different, named shift1, shift2, shift3, etc. The last really key part is line 11, which declares a few different transform properties, the first three of which use the $i
variable, so they will be different for each div. For the first div it’ll look like this:
[css]
transform:rotate(60deg) translateX(5px) translateY(5px) scale(2);
[/css]
Then for the second div it’ll be:
[css]
transform:rotate(120deg) translateX(10px) translateY(10px) scale(2);
[/css]
And for the third div it’ll be:
[css]
transform:rotate(180deg) translateX(15px) translateY(15px) scale(2);
[/css]
You get the idea. It should make for an interesting effect, let’s check it out below.
CodePen style
Here’s the result on CodePen. But don’t stop here, now the fun part really begins. Try changing the values where the transforms are defined, or the animation timing values. What happens when you tweak this number here or this property there? Feel free to fork the pen below or just start your own from scratch, and if you do please let me know what you come up with, either by commenting here or on twitter (@therealmarklee). And above all, have fun!
Check out this Pen!