Create an Icon Pulse Animation with Pure CSS
A small animation can bring life to your interface. One of the simplest but most effective effects is a pulse animation. It’s perfect for notification icons, alert buttons, or anything that needs to attract gentle attention.
With only a few lines of CSS, you can create a glowing ripple that expands around your icon, fading out as it grows. The best part – it works without JavaScript or external animation libraries.
Today you’ll learn how to make a beautiful icon pulse animation using pure CSS.
The Idea
The pulse effect works by layering invisible circles behind the main icon. These circles expand and fade out repeatedly, creating the illusion of a glowing pulse.
We’ll achieve this by using the ::before and ::after pseudo-elements. They will serve as two animated waves that alternate in timing, giving a smooth and continuous pulse.
It’s a neat CSS trick that looks advanced but is surprisingly easy to implement.
The HTML Setup
The HTML is as simple as it gets. You only need a wrapper around the icon and the icon itself. You can use any icon library, such as Font Awesome, Material Icons, or your own SVG.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css">
<div class="pulse">
<i class="fas fa-bell"></i>
</div>
That’s it for HTML. Now it’s time to bring it to life with CSS.
The CSS Magic
We’ll create a circular container for the icon and apply a gradient background. Then we’ll use ::before and ::after to generate expanding layers.
.pulse {
height: 5rem;
width: 5rem;
background: linear-gradient(#65c0e7, #22a5dd);
border-radius: 50%;
display: grid;
place-items: center;
color: #fff;
font-size: 2rem;
position: relative;
}
.pulse::before,
.pulse::after {
content: "";
position: absolute;
height: 100%;
width: 100%;
background-color: #65c0e7;
border-radius: 50%;
opacity: 0.7;
z-index: -1;
}
.pulse::before {
animation: pulse 2s ease-out infinite;
}
.pulse::after {
animation: pulse 2s 1s ease-out infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
opacity: 0.7;
}
100% {
transform: scale(2.5);
opacity: 0;
}
}
Now you have a glowing bell icon surrounded by two expanding rings that fade out smoothly. Because one animation starts with a delay, it creates a seamless looping pulse effect.
How It Works
Let’s break it down step by step:
- The base icon is inside a round
.pulsecontainer. - The pseudo-elements
::beforeand::afterare absolutely positioned behind the icon. - The keyframes control their scale and opacity.
- The delay on
::aftermakes the second wave start halfway through the first one, creating a continuous rhythm.
Each wave expands from the center, becomes transparent, and resets – repeating forever. The visual result is a steady pulse radiating from your icon.
Customization Options
This animation is easy to tweak and adapt to your design. Here are a few ideas:
- Change the color by adjusting the background gradient or the
background-colorin pseudo-elements. - Adjust the speed by changing the duration in
animation: pulse 2s. - Change the intensity by increasing or decreasing the final
scale()value. - Add shadows for extra glow:
.pulse {
box-shadow: 0 0 15px rgba(34,165,221,0.6);
}
- Replace the icon with any Font Awesome symbol, an SVG, or even an emoji.
The effect is versatile enough for notification badges, call-to-action buttons, and live indicators.
Performance and Browser Support
This technique uses only CSS properties that are well supported across all major browsers: Chrome, Firefox, Edge, and Safari. It doesn’t require heavy rendering, so it runs smoothly even on mobile devices.
Because everything is built using pseudo-elements and keyframes, there’s no need for extra HTML elements or JavaScript listeners.
Accessibility and Usability
Animations should never distract users from their main task. Use pulse animations sparingly and with purpose. For example, they’re great for:
- Drawing attention to a new message or update
- Highlighting an active element in a dashboard
- Signaling background activity like syncing or refreshing
Keep in mind that users sensitive to motion might prefer reduced animations. You can respect their preferences with this small addition:
@media (prefers-reduced-motion: reduce) {
.pulse::before,
.pulse::after {
animation: none;
}
}
That ensures your animation pauses automatically for users who have motion reduction enabled in their system settings.
Wrap-up
With just a few lines of CSS, you’ve created a smooth and visually appealing pulse animation around an icon.
This is a perfect example of how CSS pseudo-elements and keyframes can replace complex JavaScript effects.
It’s light, efficient, and elegant – ideal for modern UI designs where small interactive details make a big difference.
Try applying it to your buttons, notification icons, or call indicators, and you’ll see how a small pulse can make your interface feel more alive.