Day 10: 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.
The path of this arm also covers something we will cover later: a cubic bezier curve. The path segment starting with the letter C draws the bottom round part of this arm. We will cover curves in detail in upcoming chapters.
<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.
<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 element moves the head of the windmill into the correct position. We translate
the head by -50 units.
We assign the ID windmill-head to the inner group and set a keyframe animation in CSS that rotates the head. Note that when we set the rotation in CSS, we need to add the unit of measurement.
<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"></circle>
<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>
<style>
#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);
}
}
</style>