Hey all!
Time for a yet another CSS Funstuff tutorial! This time, we'll be creating an animated spinner with pure HTML+CSS! I have to warn you though, this one is a little longer than usual.
After all, it comes with territory, working with CSS.
Let's get right to it!
1st! Setting Up The Basics:
First, as always, let's style the background and set up some defaults. I use the same style in every project in this series, as you probably know by now.
* { box-sizing: border-box; margin: 0; padding: 0; } body { background-color: rgb(35, 35, 35); display: flex; justify-content: center; align-items: center; height: 100vh; }
2nd: Building Our Spinner Object in HTML:
We'll need one div for the inside of the spinner, which ironically, is the container for everything else. What can I say? CSS - it's fascinating.
<div class="spinner"> </div>
We'll set up the CSS later, but for now, let's go ahead and add the divs that will make up the rest of the spinner.
<div class="spinner"> <div class="n-s"> </div> <div class="w-e"> </div> <div class="nw-se"> </div> <div class="sw-ne"> </div> </div>
You'll notice I've named the classes:
- "n-s"
- "w-e"
- "nw-se"
- "sw-ne"
These names are not chosen at random, and if you have your thinking cap on, you've probably figured out what their names stand for:
- "north->south"
- "west->east"
- "northwest->southeast"
- "southwest->northwest"
Essentially, these are "navigation points" for where we'll be placing the pseudo-elements that make up the rest of our spinner. From this point onward, we'll only be tackling CSS.
The CSS Funstuff!
First let's set up a CSS keyframe animation called spin
. It's always good to keep in mind how things cascade in CSS. It will give our spinner rotation, as well as set the border of the .spinner
class.
@keyframes spin { 0% { border-color: rgba(255, 0, 0, .735); transform: rotate(0deg); } 50% { border-color: rgba(255, 0, 0, .235); } 100% { border-color: rgba(255, 0, 0, .735); transform: rotate(360deg); } }
Next, let's style the .spinner
class.
.spinner { animation: spin 5s linear 0s infinite normal; border: 2px solid; border-radius: 50%; height: 50px; position: relative; width: 50px; }
We'll set up another animation next, this time called pulse
:
@keyframes pulse { 0% { opacity: .5; transform: scale(0); } 50% { opacity: 1; transform: scale(1); } 100% { opacity: .5; transform: scale(0); } }
Now you may be wondering, where will this one go? After all, we've already animated the .spinner
class! Well, that's where the pseudo elements come into play:
.spinner::before, .spinner::after { border-radius: 50%; content: ''; inset: 0; position: absolute; } .spinner::after { animation: pulse 1s linear 0s infinite normal; border: 1px solid rgba(255, 0, 0, .35); } .spinner::before { animation: pulse .735s linear .235s infinite normal; border: 5px solid rgba(255, 0, 0, .135); }
Now, we'll position all the child divs as needed:
.spinner div { position: absolute; height: 100%; width: 100%; left: 50%; top: 0; }
This piece won't be visible, but it's essential.
At this point, you should have something that looks like this:
Following this, we're going to build the rest of the spinner animation. It's a bit of work, so be prepared for reading a lot of code!
Setting up the animation:
As before, we'll tackle the animation first:
@keyframes stretch { 0% { opacity: 0; transform: scaleY(0); } 50% { opacity: 1; transform: scaleY(1.5); } 100% { opacity: 0; transform: scaleY(0); } }
All the moving parts:
Remember the four classes we added earlier, .n-s
, .w-e
, .sw-ne
, and .nw-se
? Well, the final step is for us to style them:
.spinner div::before, .spinner div::after { animation: stretch 2s linear 0s infinite; animation-fill-mode: both; background-color: white; content: ''; height: 15px; left: -2.5px; position: absolute; width: 5px; z-index: -1; } .spinner div:after { top: -50%; } .spinner div::before { bottom: -50%; } .spinner .nw-se, .spinner .sw-ne, .spinner .w-e { left: 0; } .spinner .w-e { top: calc(50% - 2.5px); transform: rotate(90deg); } .spinner .sw-ne { transform: rotate(45deg); } .spinner .nw-se { transform: rotate(-45deg); } .spinner .nw-se::before, .spinner .nw-se::after, .spinner .sw-ne::before, .spinner .sw-ne:after { left: calc(50% - 2.5px); left: calc(50% - 2.5px); } .spinner .sw-ne:after { animation-delay: .125s; } .spinner .w-e:after { animation-delay: .25s; } .spinner .nw-se:after { animation-delay: .35s; } .spinner .n-s:before { animation-delay: .5s; } .spinner .sw-ne:before { animation-delay: .65s; } .spinner .w-e:before { animation-delay: .75s; } .spinner .nw-se:before { animation-delay: .85s; }
The Final Product:
When it's all said and done, this is what you should get:
That's all for now! But wait, there's more! Download the source code. I'll soon update the source with a couple fun tweaks, as I often do in this series, so be on the look out!
[Visit my Gumroad page] for(https://rolandixor.gumroad.com) more like this.
Top comments (0)