Skip to main content

Create cool UI animations with CSS

SVG has many benefits – its vector nature is great, and we don't get any of the problems we get with bitmap images when displaying an image too big or too small or on devices with differing DPIs. SVG is also much smaller in size. SVGs are basically instructions for the browser to draw the image contained within.

How do I animate SVG?

SVG enables us to create intricate drawings and images, where all of the elements inside SVG can be animated using CSS.

Animation in SVG works exactly the same way as it does with any element on the page. We need some way to target the element we want to animate, and then apply the animation.

svg rect {
  animation: 2s linear infinite rotate;

The main way in which animating SVG elements differs from regular elements is the transform-origin property. Normally we would use percentages or keyword values in order to set the point at which a transform operation takes place.

transform-origin: 50% 50%;
transform-origin: center center;}

So if we can't use keywords and can't use percentages, how do we set our transform origin? The answer is to use pixel values. Further complications come into play because, unlike regular elements that would measure the pixels from the top left corner of itself, SVGs will measure from the top left corner of the parent SVG canvas. This blog post covers the topic in detail.

Finally, a note on browser support: CSS animation when used with SVG requires the SVG to be inline in the page for the majority of browsers. This means we can't use the image tag to include our SVG and perform animations; we need to have our SVG inside an SVG tag on the page.

desktop windows illustration

Custom properties

Custom properties, or CSS variables, can be used to create configurable parts of your animation. Animations and movement can cause motion sickness in some users. We can use custom properties in order to effectively remove animations for users who have indicated preferring reduced motion.

:root {
  --timing: 500ms;
@media (prefers-reduced-motion: reduce) {
  --timing: 0;
.animate {
  animation: my-animation var(--
timing) linear;

By changing the timing to 0, we stop the animation from running when the user has requested it. While this media query isn't yet widely supported, it is by iOS.

We can use custom properties to define other parts of our animation, such as the colour or size and use. This is useful if we have a part that's configurable and we're using that property as part of an animation.

Next page: Bring everything together in a UI animation