How to Add Animation on Hover for an SVG Element

We can define keyframe animations for SVG elements with CSS. In this example, we animate the transform property with keyframes. Here, we trigger this effect on mouse hover.

How to Draw Quadratic Bézier Curves with SVG

Drawing a Bell

First, let’s define the bell as an SVG. We draw the bell as a path with cubic and quadratic Béziers curves and straight line segments. Let’s start with the bottom. We begin with a move-to command and then use the line-to command to draw straight lines.

-100, -100
-50, 40 -50, 50 50, 50 50, 40 -50, 40 -50, 50 50, 50 50, 40
200, 200
<svg
width="200"
height="200"
viewBox="-100 -100 200 200"
stroke="black"
stroke-width="2"
>
<path
d="
M -50 40
L -50 50
L 50 50
L 50 40"
fill="#FDEA96"
/>
</svg>

Then a quadratic Beziers starts the bell cloak. Hover over the coordinates in the code or on the image to see how they are positioned.

-100, -100
-50, 40 -50, 50 50, 50 50, 40 40, 40 40, 10 40, 40 -50, 40 -50, 50 50, 50 50, 40 40, 40 40, 10 40, 40
200, 200
<svg
width="200"
height="200"
viewBox="-100 -100 200 200"
stroke="black"
stroke-width="2"
>
<path
d="
M -50 40
L -50 50
L 50 50
L 50 40
Q 40 40 40 10"
fill="#FDEA96"
/>
</svg>

Then the line is continued with a cubic Bezier to form the top of the bell.

-100, -100
-40, -60 40, -60 -50, 40 -50, 50 50, 50 50, 40 40, 40 40, 10 40, -60 -40, -60 -40, 10 -40, -60 40, -60 -50, 40 -50, 50 50, 50 50, 40 40, 40 40, 10 40, -60 -40, -60 -40, 10
200, 200
<svg
width="200"
height="200"
viewBox="-100 -100 200 200"
stroke="black"
stroke-width="2"
>
<path
d="
M -50 40
L -50 50
L 50 50
L 50 40
Q 40 40 40 10
C 40 -60 -40 -60 -40 10"
fill="#FDEA96"
/>
</svg>

Then we reach the bottom part with another quadratic bezier that mirrors the previous one.

-100, -100
-50, 40 -50, 50 50, 50 50, 40 40, 40 40, 10 40, -60 -40, -60 -40, 10 -40, 40 -50, 40 -40, 40 -50, 40 -50, 50 50, 50 50, 40 40, 40 40, 10 40, -60 -40, -60 -40, 10 -40, 40 -50, 40 -40, 40
200, 200
<svg
width="200"
height="200"
viewBox="-100 -100 200 200"
stroke="black"
stroke-width="2"
>
<path
d="
M -50 40
L -50 50
L 50 50
L 50 40
Q 40 40 40 10
C 40 -60 -40 -60 -40 10
Q -40 40 -50 40"
fill="#FDEA96"
/>
</svg>

We finish the bell, by adding two circles for the bell-clapper, and the hanger.

<svg width="200" height="200" viewBox="-100 -100 200 200">
<g stroke="black" stroke-width="2">
<circle cx="0" cy="-45" r="7" fill="#4F6D7A" />
<circle cx="0" cy="50" r="10" fill="#F79257" />
<path
d="
M -50 40
L -50 50
L 50 50
L 50 40
Q 40 40 40 10
C 40 -60 -40 -60 -40 10
Q -40 40 -50 40"
fill="#FDEA96"
/>
</g>
</svg>

Adding Animation on Hover

Now, let’s add an id for the elements we move. We assign an id to the group containing the whole bell and one for the bell clapper.

<svg width="200" height="200" viewBox="-100 -100 200 200">
<g id="bell" stroke="black" stroke-width="2">
<circle cx="0" cy="-45" r="7" fill="#4F6D7A" />
<circle id="bell-clapper" cx="0" cy="50" r="10" fill="#F79257" />
<path
d="
M -50 40
L -50 50
L 50 50
L 50 40
Q 40 40 40 10
C 40 -60 -40 -60 -40 10
Q -40 40 -50 40"
fill="#FDEA96"
/>
</g>
</svg>

Then, we can add a keyframe animation on hover on the bell and the bell clapper. We use the same animation that alternates the rotation back and forth for both of them. We also set the timing function to ease-in-out to slow the animation at the leftmost and rightmost positions.

#bell {
transform-origin: 0 -45px;
}
svg:hover #bell,
svg:hover #bell-clapper {
animation-duration: 0.5s;
animation-delay: -0.25s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: ease-in-out;
animation-name: ring;
}
@keyframes ring {
from {
transform: rotate(-20deg);
}
to {
transform: rotate(20deg);
}
}

Notice that we also set the transform-origin property for the group. This ensures that the rotation occurs around the bell hanger and not the origin of the coordinate system.