CSS pulse animation on hover
Create smooth looking pulse css animations for your website designs.
Apr 14, 2022 | Read time 9 minutes🔔 Table of contents
In this post we will go over how to do pulse animation effect with CSS. Pulse animations can be used to give your interface a slick look and draw the user’s attention. They are commonly used with loading animations and sign up buttons.
What is a pulse animation?
Pulse animations can be seen in hamburger menus, sign up buttons or even thumbnails in a image gallery. These effects usually take shape of a smaller circle in the beginning of the animation and then expand as the animation progresses.
For example when the user hovers over the
button, a pulse will show encouraging them to click the button. We can create pulse animation effects with CSS
and
with SVG
images.
The key CSS
property that can give us this effect is the transition:scale()
function!
How to create pulse animation on hover
We create a basic circular button and and when hovered, it will give out a pulse effect. This will only require knowledge of CSS
and @keyframes
To create the following effect, we use the following steps:
- create a circular button using
border-radius:50%
- define the keyframes.
The HTML is very basic, we just have one div
that is the container, and a span
as the button.
<div class='container'>
<span class='pulse-button'>Click me</span>
</div>
We can then style the button as the below. The button is circular so we need to use border-radius: 50%;
. We also define the animation on hover - using the pulse keyframes and animating it
for 1.5 seconds.
.pulse-button {
position: relative;
top: 50%;
left: 50%;
margin-left: -50px;
margin-top: -50px;
display: block;
width: 100px;
height: 100px;
font-size: 1.3em;
font-weight: light;
font-family: 'Trebuchet MS', sans-serif;
text-transform: uppercase;
text-align: center;
line-height: 100px;
letter-spacing: -1px;
color: white;
border: none;
border-radius: 50%;
background: #5a99d4;
cursor: pointer;
box-shadow: 0 0 0 0 rgba(#5a99d4, .5);
}
.pulse-button:hover {
animation: pulse 1.5s; /* Animate for 1.5 seconds on hover */
}
The @keyframes
can be defined as below. The key idea is to start the animation with the button 85% of its initial size (smaller). As the animation progresses, we
use the box-shadow
property. This will give us a ripple effect behind our button when the user hovers. We will make the box shadow spread 50px and the colour to be blueish (#5a99d4).
As the animation finishes, we change the button back to its original size of 100% (scale(1)) and the box-shadow
spread to be 0.
So the browser will fill in the keyframes, giving the impression that the button is growing slowly and its box shadow to expand - giving the pulsing animation effect.
@keyframes pulse {
0% {
transform: scale(.85);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 50px rgba(#5a99d4, 0);
}
100% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(#5a99d4, 0);
}
}
👉 What is the CSS scale()
function?
The scale()
CSS function is the core of how to get this pulsating animation to work. As referenced in MDN https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scale
the function scales a element along the 2D plane.
We can use this with the transform
CSS property. When given the scale()
function just one parameter - its treated like a percentage.
So a value of 1.2 (scale(1.2)) is treated like 120%. If we pass in two values such as scale(2, 0.5)
this means that we scale it 200% on the x axis and 50% on the y axis:
.scale1 {
transform: scale(1.2); /* Equal to scaleX(1.2) scaleY(1.2) - scale to 120% */
}
.scale2 {
transform: scale(2, 0.5); /* Equal to scaleX(2) scaleY(0.5) - results in a stretched rectangular effect*/
}
Pulse loading animation with CSS
In the following, we will go over another example of a pulse animation - using it for loading animations. This is great use of pulse animations since it does not require much HTML and CSS and since it is a loading animation, we need to it render quickly.
The HTML is quite simple, just one div
with a class of pulseLoader.
<div class="pulseLoader"></div>
Similar to the above example of a pulsating button on hover, to style our loading element, we need to make it circular so have to use the property border-radius: 50%;
.
Keep in mind that since this div
does not have any content, we have to explicitly define the width and height. I have just made it responsive and using 40vh
. This just means
that the div
is 40% of the view height (width and height to be the same).
.pulseLoader {
width: 40vh;
height: 40vh;
border-radius: 50%;
background-color: white;
outline: 1px solid transparent;
animation: pulse 1.5s ease-in-out infinite; /* define to use the pulse animation keyframes and duration of 1.5 seconds and repeat infinitely */
}
Now to define the @keyframes
, we just want the div
to be scaled to 0% in size (not visible) in the begining of the animation and have a opacity of 0.8 (somewhat transparent).
As the animation progresses, the div will finish to be scaled to 100% of its original size and opacity of 0 (fully transparent).
This gives us the effect of a circular element growing but also disappearing as the animation progresses.
@keyframes pulse {
0% { transform: scale(0); opacity: 0.8;}
100% { transform: scale(1); opacity: 0;}
}
Browser support
Browser support for this type of animation is good across modern browsers such as chrome, firefox safari, etc. Even IE has support with a few edge cases (such as using the !important) keyword.
- https://caniuse.com/mdn-css_types_transform-function_scale
- https://caniuse.com/mdn-css_at-rules_keyframes_ignore_important_declarations
Animation performance
If performance is of a concern for your web design, then preferably we should use scale3d
CSS function instead of the regular scale
function.
The scale3d
function allows you to resize an element in 3D space and has the following signature:
scale3d(sx, sy, sz)
sx - representing the x-component of the scaling vector.
sy - representing the y-component of the scaling vector.
sz - representing the z-component of the scaling vector.
.scaled {
transform: perspective(500px) scale3d(2, 0.7, 0.2) translateZ(100px);
transform-origin: left;
background-color: pink;
}
Using scale3d
we can take advantage of hardware acceleration on our animation. The processing tasks will be offloaded from the main CPU an directed to the
GPU. This can lead to performance improvements when you have lots of animations already or the user’s device is not of high spec.
Additionally offloading to the GPU will see less janky animations~
Final thoughts
In this post, we went through on how to create a pulse animation on hover effect with CSS. The key techniques that is required to create this effect
is the tranform:scale()
function and box-shadow
. Pulse animations are usually circular so we also need to style the element as a circle with the
border-radius:50%
CSS property.
We use @keyframes
to define the animation, with the start of the animation the scale the element to be smaller and then expand to its 100% size as the
animation progresses to completion. To give an effect of a pulsating ripple, we define the element’s box-shadow to also spread and contract as the animation
moves through its timeline.
As with any CSS animations, we need to consider browser support and fallbacks. This effect will be supported by most modern browsers (chrome, safari, firefox, etc) with the exception of IE 11 or lower with limited support.
Additionally animation performance is a consideration - using scale3d()
instead of the regular scale()
CSS function for hardware acceleration (offloading tasks from the
CPU to the GPU to handle).