DEV Community

loading...
Cover image for Animated CSS Sparkler

Animated CSS Sparkler

Johnny Fekete
Proud millennial, traveler, startupper. I mix Laravel with React, and prefer GUI's over terminal commands. πŸ‘¨β€πŸ’» πŸ³οΈβ€πŸŒˆ
・3 min read

CSS animations can be super powerful and combined in the correct way you can achieve pretty much anything.

In this short tutorial, I explain how I created this animated sparkler with only HTML + CSS:

Alt Text

Source code on CodePen

Let's dissect the animation:

  • there's the stick that's burning with an ember and leaves the ashes behind
  • the light, that's constantly pulsating, and moving together with the burn
  • the sparks that are randomly showing up and fading out from the center, the burn

The Burning Stick

The stick has two overlapping elements: one that is the ash and one with the animation. I used a DIV and a ::before pseudo-class for the styling.

As you can see in the example, the ember and the explosive cover is drawn by a linear gradient, and the burning effect happens by a keyframe animation, that simply decreases the height of the overlaying element in 20 seconds.

.gun-powder::before {
  content: '';
  display: block;
  position: absolute;
  bottom: 0;  /* this is needed so the burning starts 
                 at the top and ends at the bottom */
  width: 0.4rem;
  height: 10rem;
  background: linear-gradient(to bottom,
    orange 0.3rem,
    gray 0.4rem
  );
  border-radius: 0.5rem;
  animation: sparkler-burn-anim 20s infinite;
}

@keyframes sparkler-burn-anim {
  0%   {
    height: 10rem
  }
  100% {
    height: 0 
  }
}
Enter fullscreen mode Exit fullscreen mode

Pulsating Light

The pulsating light is used for two things: besides showing a glow of the sparkles, it also functions as a container for them, and it moves together with the burn (so the sparks don't have to deal with moving while the burning takes place, just with the sparkling animation).

The glow effect has been created with another keyframe animation on the ::after pseudo-class, and it uses a simple scale transform to grow and shrink, resulting the pulsating effect:

.sparkler-light::after {
  content: '';
  display: block;
  border-radius: 50%;
  width: 9rem;
  height: 9rem;
  background-color: rgba(255, 255, 230, 0.05);
  animation: sparkler-light-pulsating 2s infinite linear;
}

@keyframes sparkler-light-pulsating {
  0%   {
    transform: scale(1);
  }
  25%   {
    transform: scale(1.1);
  }
  75%   {
    transform: scale(0.9);
  }
  100% {
    transform: scale(1);
  }
}
Enter fullscreen mode Exit fullscreen mode

The .sparkler-light moves together with the burn, and as I wrote, it contains all the sparks.

<div class="sparkler-light">
  <div class="spark"></div>
  <div class="spark"></div>
  ... further sparks, 36 in total
</div>
Enter fullscreen mode Exit fullscreen mode
.sparkler-light {
  position: absolute;
  width: 9rem;
  height: 9rem;
  margin-left: -4.4rem;
  margin-top: -1.4rem;
  animation: sparkler-light-anim 20s infinite;
}

@keyframes sparkler-light-anim {
  0%   {
    bottom: 11.5rem
  }
  100% {
    bottom: 1.5rem;
  }
}
Enter fullscreen mode Exit fullscreen mode

Sparkling ✨

It's not possible to use random values in CSS. But what's possible is to assign random numbers to CSS variables, and use those.

I created 36 DIVs for the sparkles, each with the same animation, but setting two CSS variables:

<div class="sparkler-light">
  <div class="spark" style="--spark-rotate: 10deg; --spark-delay: 223ms"></div>
  <div class="spark" style="--spark-rotate: 20deg; --spark-delay: 844ms"></div>
  ...
  <div class="spark" style="--spark-rotate: 360deg; --spark-delay: 559ms"></div>
</div>
Enter fullscreen mode Exit fullscreen mode

Then I could create the irregular order of the sparks by adding animation-delay: var(--spark-delay) on them.

I also rotated each one by 10 degrees (to make a full circle) with transform: rotate(var(--spark-rotate)).

Finally, I used a keyframe-animation to create the explosive effect.
It was important to use transform-origin: bottom center, so the sparks all originate from the same point.

The Final Sparkler

To polish everything, I applied a rotate transform on the whole sparkler, so it's not standing upwards.

I used Pug templating engine, to facilitate the typing (especially with the 36 sparks, with their random values), you can read more about it in the Type Less! Use Pug Templates! article.

The CSS Christmas Calendar

CSS Christmas Calendar

This rotating 3D Christmas gift is part of my Holiday project, the CSS Christmas Calendar. I posted a new calendar item every single day from the 1st of December until Christmas Eve.

I tried different techniques each day and learned a lot - and I share the most interesting techniques in this series.

All code is available on Codepen.

Check it if you want to see other Christmassy CSS magic!

Discussion (0)