How to Animate an SVG with CSS

You can move some SVG properties to CSS and even animate them with CSS keyframes. In this example, we create a spinning windmill.

Draw the head of the windmill

Let’s start by composing the windmill’s head. Thanks to its central symmetry, we can define a single arm and reuse this element with a rotation.

How to Draw Basic Paths with SVG

We define the arm as a path. We start with the move-to command, draw a cubic Bézier curve curve, then finish the shape with two straight lines. Hover over the coordinates in the code or on the image to see how they are positioned.

-100, -100
-7, -20 -7, -10 7, -10 7, -20 2, -80 -2, -80 -7, -20 -7, -10 7, -10 7, -20 2, -80 -2, -80
200, 200
<svg
width="200"
height="200"
viewBox="-100 -100 200 200"
>
<path
id="arm"
d="
M -7 -20
C -7 -10 7 -10 7 -20
L 2 -80
L -2 -80"
/>
</svg>

To finish the head of the windmill, we reuse the same arm element with a rotation and add a circle to the middle.

-100, -100
0, 0 -7, -20 -7, -10 7, -10 7, -20 2, -80 -2, -80 0, 0 -7, -20 -7, -10 7, -10 7, -20 2, -80 -2, -80
200, 200
<svg
width="200"
height="200"
viewBox="-100 -100 200 200"
>
<circle r="8" />
<path
id="arm"
d="
M -7 -20
C -7 -10 7 -10 7 -20
L 2 -80
L -2 -80"
/>
<use
href="#arm"
transform="rotate(+120)" />
<use
href="#arm"
transform="rotate(-120)" />
</svg>

Finish the windmill and add CSS animation

To finish the windmill, we add a stand and wrap the head of the windmill into two group elements. The outer group positions the head, and the inner will do the rotation.

We translate the outer group by -50 units to position the head.

We assign the id windmill-head to the inner group and set a keyframe animation in CSS that rotates the head.

<svg
width="200"
height="400"
viewBox="-100 -200 200 400"
fill="rgba(0, 0, 0, 0.5)"
>
<g transform="translate(0, -50)">
<g id="windmill-head">
<circle r="8" />
<path id="arm" d="M -7 -20 C -7 -10 7 -10 7 -20 L 2 -80 L -2 -80" />
<use href="#arm" transform="rotate(+120)" />
<use href="#arm" transform="rotate(-120)" />
</g>
</g>
<path d="M -7 100 L 7 100 L 3 -35 L -3 -35" />
</svg>
#windmill-head {
animation-name: rotate;
animation-duration: 4s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

When we set the rotation in CSS, we need to add the unit of measurement.