CSS Pulse Animation

CSS Pulse Animation
August 22, 2025 | Read time: 3 minutes

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.

Try Sevalla with $50 credit now

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.

Learn more

Sponsor this newsletter to reach 9,000+ active developers

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;
}                            
                        

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);
  }
}                            
                        

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.