I work on the internal applications in Bekk, including a front page that shows key information about employees and the company. One of the sections shows upcoming birthdays, so you can congratulate your colleagues on their big day. But something was missing. You know, that little extra that tends to light up people’s faces. How about some confetti bursting out the top of your head? 🎉
The goal was to make it as simple and quick as possible. No flashy frameworks, just plain HTML, CSS and JS. You can see the final result below. Let’s take a closer look at how it was made.
On our internal front page we have a carousel with employees, sorted by birthdays. Every upcoming birthday boy or girl has their own “card” in the carousel, with their image on it. Let’s say each card looks like this:
<div id="employeeId" class="employeeCard">
<img ... />
</div>
For simplification, let’s say that each employee object consists of three properties:
{
id: 1,
name: "Santa",
hasBirthdayToday: true,
}
We can then define a method that's applied to every employee in the carousel, to check if they should have confetti or not.
function applyBirthdayConfetti(employee) {
if (employee.hasBirthdayToday) {
// Make confetti!
}
}
We want to attach the confetti to the card if their birthday is today. First, we need to get a hold of their card in the DOM. Luckily, the DOM API provides us with the method document.getElementById()
. Since each card in the DOM uses the employeeId
as its id, we can do the following to get a hold on that card:
function createBirthdayConfetti(employee) {
if (employee.hasBirthdayToday) {
const card = document.getElementById(`${employee.id}`);
// Make confetti!
}
}
This enables us to manipulate the element in the DOM. We can append child elements to it during runtime!
What is confetti, anyway? Isn’t it just a collection of many small, colored dots, spread in multiple directions? That doesn't sound too complicated. And you guessed it – that’s exactly what we’re going to make next!
First, we create a new element, and add a className
for styling:
let dot = document.createElement("div");
dot.className = "confetti";
Time to look at some CSS. If you're not familiar with the variables we have used, I'll explain that below. We define the styling for each dot, and an animation to go with it:
.confetti {
position: absolute;
width: 4px;
height: 4px;
top: 10%;
left: 50%;
margin: -2px 0 0 -2px;
opacity: 0;
background: var(--color);
transform: translate(var(--endX), var(--endY)) scale(var(--scale, 1));
animation: confetti 1s ease-out 1s forwards;
}
@keyframes confetti {
from {
transform: translate(0, 0);
opacity: 1;
}
}
Okay, so we provided some custom variables to our style by writing var(--name)
. This allows us to vary the colors and animated motions of the dots. Now, we need to define these custom variables in our code to be able to access them in the CSS. They are defined in JavaScript using the style property of the dot element, supplying a property name and a value: dot.style.setProperty('--color', 'red');
We want the confetti dots to start from the same source, but end up in different, seemingly random x and y positions.
To simulate this randomness in our confetti, we create a simple method. It gives us a pseudo-random number within a specified range that we can use to set the end positions of x and y.
const random = (min, max) => {
return Math.floor(Math.random() * (max - min + 1) + min);
};
Let’s go ahead and define our custom properties using our random function:
dot.style.setProperty("--endX", random(-260, 260) + "px");
dot.style.setProperty("--endY", random(-160, 160) + "px");
dot.style.setProperty("--scale", random(0.6, 1) + "");
Lastly, let’s define some happy colors for our confetti.
const colors = ["#a864fd", "#29cdff", "#78ff44", "#ff718d", "#fdff6a"];
dot.style.setProperty("--color", colors[random(0, 4)]);
Then, we append the dot to the card using the method appendChild()
.
Puh! Let’s take a look at the result:
There you go! Awesome confetti with a few lines of code and no sweat. How about playing around with some confetti this holiday? Feel free to use it in your own project, and play with the different variables to customise it.
And remember: With great confetti comes great joy! :tada: :star_struck: