CSS Pulse Animation
Escape the vendor-locked in edge-runtime!
Sevalla is the home to your web projects. Host and manage your applications, databases, and static sites in a single, intuitive platform.
supastarter - The production-ready and scalable SaaS starter kit for Next.js, Nuxt and SvelteKit
Join over 800 developers and founders already using supastarter to turn their ideas into profitable SaaS businesses. Our production-ready boilerplate helps you save countless hours of development and gives you a scalable foundation, so you can focus on delivering value to your customers — not reinventing the wheel. supastarter comes with authentication, payments, dashboards, multi-tenancy and many more essential SaaS features built in, so you can launch sooner, grow faster, and stay ahead of the competition.
In this article, I’ll show you how to create a beautiful pulse effect. I’ll also discuss the use cases and explain how you can improve performance.
Let’s get started!
HTML element
First, we need one HTML element. Let’s give it the class .pulse. It can be an empty <div> as we don’t need any content here, at least not for this basic example.
<div class="pulse"></div>
Circle
Now we need some styles to make this element look like a circle.
.pulse {
background: rgb(222, 84, 72);
border-radius: 50%;
height: 30px;
width: 30px;
}
Animation
Next, we will create this animation using the box-shadow and transform properties.
The box-shadow property adds a shadow around elements. The transform property lets you rotate, scale, skew, or translate an element.
.pulse {
background: rgb(222, 84, 72);
border-radius: 50%;
width: 30px;
height: 30px;
box-shadow: 0 0 0 0 rgba(222, 84, 72, 1);
transform: scale(1);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(222, 84, 72, 0.7);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 15px rgba(222, 84, 72, 0);
}
100% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(222, 84, 72, 0);
}
}
This will already work, but let’s make it a more realistic example by making it a bit more dynamic.
For this purpose, I will rewrite the previous demo and use CSS variables to make it reusable. I will create four elements with different colors.
HTML:
<div class="pulse-wrapper">
<div class="pulse red"></div>
<div class="pulse blue"></div>
<div class="pulse green"></div>
<div class="pulse yellow"></div>
</div>
CSS:
.pulse-wrapper {
min-height: 300px;
display: flex;
align-items: center;
justify-content: space-evenly;
}
.pulse {
background: rgb(var(--pulse-color));
border-radius: 50%;
height: 30px;
width: 30px;
box-shadow: 0 0 0 0 rgba(var(--pulse-color), 1);
transform: scale(1);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(var(--pulse-color), 0.7);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 15px rgba(var(--pulse-color), 0);
}
100% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(var(--pulse-color), 0);
}
}
/* Define different color circles */
.pulse.red {
--pulse-color: 222, 84, 72;
}
.pulse.blue {
--pulse-color: 66, 103, 178;
}
.pulse.green {
--pulse-color: 76, 175, 80;
}
.pulse.yellow {
--pulse-color: 255, 210, 63;
}
Let’s see what it looks like:
This is it, but I’ll provide one more example for you. Let’s create a ‘play’ button you can use to make a CTA if you have some videos on your website.
In this example, we’ll need a bit more HTML and CSS, but I promise it will be fun. 🙂
HTML:
<div class="pulse-wrapper">
<div class="pulse-play-button">
<div class="pulse-play-icon"></div>
</div>
</div>
CSS:
.pulse-wrapper {
min-height: 300px;
display: flex;
align-items: center;
justify-content: space-evenly;
}
.pulse-play-button {
--pulse-color: 222, 84, 72;
background: rgb(var(--pulse-color));
border-radius: 50%;
height: 80px;
width: 80px;
box-shadow: 0 0 0 0 rgba(var(--pulse-color), 1);
transform: scale(1);
animation: pulse 2s infinite;
position: relative;
}
.pulse-play-icon {
border-left: 30px solid #fff;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
position: absolute;
top: 20px;
left: 28px;
}
@keyframes pulse {
0% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(var(--pulse-color), 0.7);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 15px rgba(var(--pulse-color), 0);
}
100% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(var(--pulse-color), 0);
}
}
Here it is:
What about performance, Marko?
We can make it more performant by adding the will-change property. For example, will-change: transform, box-shadow; helps the browser optimize animations for smoother performance.
Like this:
.pulse-play-button {
--pulse-color: 222, 84, 72;
background: rgb(var(--pulse-color));
border-radius: 50%;
height: 80px;
width: 80px;
box-shadow: 0 0 0 0 rgba(var(--pulse-color), 1);
transform: scale(1);
animation: pulse 2s infinite;
position: relative;
will-change: transform, box-shadow; /* Optimizes animation for smoother performance */
}
Should the next newsletter focus on CSS tips or monetization? Let me know!
Thanks for reading!
See you next Saturday.