authors are vetted experts in their fields and write on topics in which they have demonstrated experience. All of our content is peer reviewed and validated by Toptal experts in the same field.
Filip Defar's profile image

Filip Defar

Filip is a web developer with expertise in highly interactive front-end applications. He helped build data visualizations for several BI products while working for companies such as AlignAlytics and Captario.

Years of Experience

10

Share

Animations are a ubiquitous part of the web. Unlike the flashing GIF images that plagued websites in the internet’s earlier days, today’s animations are more subtle and tasteful. Designers and front-end specialists use them to make websites look more polished, enhance the user experience, call attention to important elements, and convey information.

Web developers can benefit from combining the power of SVG and CSS to create animations without using external libraries. This SVG animation tutorial shows how to build custom animations for real-world projects.

SVG Animation: CSS and Core Concepts

Before using CSS to animate SVGs, developers need to understand how SVGs work internally. Fortunately, it’s similar to HTML: We define SVG elements with XML syntax and style them with CSS, just as if they were HTML.

SVG elements are purposely built for drawing graphics. We can use for drawing a rectangle, for drawing circles, etc.—SVG also defines , , , , and .

Note: The full list of SVG elements even includes , which allows you to create animations using synchronized multimedia integration language (SMIL). However, its future is uncertain and the Chromium team recommends using a CSS- or JavaScript-based approach to animating SVGs whenever possible.

The available attributes depend on the element, so while has width and height attributes, the element has the r attribute, which defines its radius.

Three basic SVG elements (a rectangle, circle, and line) and their available attributes. The rectangle is defined by the x- and y-coordinates of its top-left corner, as well as its width and height, e.g., <rect x="25" y="25" width="150" height="100"/>. The circle is defined by the x- and y-coordinates of its center (cx, cy) followed by its radius (r), e.g., <circle cx="75" cy="75" r="50"/>. The line is defined using start coordinates (x1 and y1) and end coordinates (x2 and y2), e.g., <line x1="40" y1="140 x2="140" y2="40"/>.
Select basic SVG elements; coordinates are relative to the origin (the top-left corner of the SVG viewport).

While most HTML elements can have children, most SVG elements cannot. One exception is the group element , which we can use in order to apply CSS styles and transformations to multiple elements at once.

The Element and Its Attributes

Another important difference between HTML and SVG is how we position elements, notably via the viewBox attribute of a given outer element. Its value consists of four numbers separated by whitespace or a comma: min-x, min-y, width, and height. Together, these specify how much of our SVG drawing we want the browser to render. That area will be scaled to fit the bounds of the viewport, as defined by the width and height attributes of the element.

When it comes to letterboxing, the ratio of the width and height attributes of the viewport may indeed differ from the ratio of the width and height parts of the viewBox attribute.

By default, the aspect ratio of the SVG canvas will be preserved at the expense of a larger-than-specified viewBox, thereby causing a smaller, letterboxed rendering within the viewport. But you can specify a different behavior via the preserveAspectRatio attribute.

This allows us to draw images in isolation and be confident that all elements will be positioned correctly no matter the context or rendering size.

An image showing how a viewBox is rendered into a viewport with a different aspect ratio while preserving the aspect ratio of the contents. On the left, a rectangular viewBox has an isometric cube centered in it. On the right, a larger square viewport has the same isometric cube, centered and scaled up, while maintaining the aspect ratio of the cube.
Maintaining the aspect ratio of an image via letterboxing.

While you can code SVG images by hand, more complex images may require a vector graphics program (our SVG animation tutorial demonstrates both techniques). My editor of choice is Affinity Designer, but any editor should provide enough functionality for the simple operations covered here.

SVG Animation Examples Using CSS Transitions and Animations

CSS transitions allow us to define the rate and duration of property changes. Instead of jumping instantly from the starting value to the end value, the values transition smoothly as in this example in which the color of an SVG circle changes when you hover over it with a mouse:

See the Pen Transition example by Filip Defar (@dabrorius) on CodePen.

We can define transitions with the transition property, which accepts the name of the property that we want to transition, the duration of the transition, a transition timing function (also known as easing function), and the length of the delay before the effect begins:

/* property name | duration | easing function | delay */
transition: margin-right 4s ease-in-out 1s;

We can define transitions for multiple CSS properties, each of which can have separate transition values. However, there are two obvious limitations to this approach.

The first limitation is that transitions are triggered automatically when a property value changes. This is inconvenient in some use cases. For example, we can’t have an animation that loops infinitely.

The second limitation is that transitions always have two steps: the initial state and the final state. We can extend the duration of the animation, but we can’t add different keyframes.

This is why a more powerful concept exists: CSS animations. With CSS animations, we can have multiple keyframes and an infinite loop:

See the Pen Animation example by Filip Defar (@dabrorius) on CodePen.

To animate CSS properties over multiple keyframes, first we need to define the keyframes using an @keyframes at-rule. The timing of keyframes is defined in relative units (percentages) because at this point, we haven’t yet defined the animation duration. Each keyframe describes the values of one or more CSS properties at that point in time. CSS animations will ensure smooth transitions between keyframes.

We apply the animation with described keyframes to the desired element using the animation property. Similar to the transition property, it accepts a duration, an easing function, and a delay.

The only difference is that the first parameter is our @keyframes name instead of a property name:

/* @keyframes name | duration | easing-function | delay */
animation: my-sliding-animation 3s linear 1s;

How to Animate SVG/CSS for a Hamburger Menu Toggle

Now that we have a basic understanding of how animating SVGs works, we can start building a classic animation—a menu toggle that smoothly transitions between a “hamburger” icon and a close button (an “X”):

See the Pen Hamburger by Filip Defar (@dabrorius) on CodePen.

This is a subtle but valuable animation. It attracts the user’s attention, informing them that the icon can be used to close the menu.

We start our demonstration by creating an SVG element with three lines:


  
  
  

Each line has two sets of attributes. The x1 and y1 represent the coordinates of the start of the line, while x2 and y2 represent the coordinates of the end of the line. We’ve used relative units to set positions. This is a simple way to ensure that image contents get resized to fit the containing SVG element. While this approach works in this case, there is one big drawback: We can’t maintain the aspect ratio of elements positioned this way. For that, we would have to use the viewBox attribute of the element.

Note that we applied CSS classes to SVG elements. There are many properties that can be changed via CSS, so let’s apply some basic styling to our SVG elements.

We’ll set the size of the element, as well as change the cursor type to indicate that it’s clickable. But to set the color and thickness of the lines, we’ll use the stroke and stroke-width properties. You might have expected to use color or border, but unlike itself, SVG sub-elements are not HTML elements, so they often have different property names:

.hamburger {
  width: 62px;
  height: 62px;
  cursor: pointer;
}
.hamburger__bar {
  stroke: white;
  stroke-width: 10%;
}

If we render at this point, we’ll see that all three lines have the same size and position, overlapping each other completely. Unfortunately, we can’t change the starting and ending positions independently via CSS, but we can move whole elements. Let’s move the top and bottom bars with the transform CSS property:

.hamburger__bar--top {
  transform: translateY(-40%);
}
.hamburger__bar--bot {
  transform: translateY(40%);
}

By moving the bars on the Y axis we end up with a decent-looking hamburger.

Now it’s time to code our second state: the close button. We rely on an .is-opened CSS class applied to the SVG element to toggle between the two states. To make the result more accessible, let’s wrap our SVG in a

Understanding the basics

  • What is an SVG used for?

    SVG (scalable vector graphics) is an XML-based markup language for describing vector images. Browsers can render images built this way cleanly at any size—creating perfect crisp edges without any blur. Additionally, SVGs tend to be significantly smaller when compared to raster images, which helps websites to load faster.

  • Is SVG better than PNG?

    SVG (scalable vector graphics) is a vector image format, which makes it ideal for user interface elements, logos, icons, diagrams, and similar images. In these cases, it will provide better image quality and smaller file size than a PNG version of the image. SVG is almost always a better choice.

  • Can an SVG be animated?

    Yes. An SVG is a vector image format that has syntax very similar to HTML, which makes it convenient for animating. Use DOM selectors to target various SVG elements and animate them using either CSS or JavaScript.

  • How do you animate SVG?

    There are several ways to animate SVG images. For moderately complex animations, the most straightforward approach is to use CSS transitions or CSS animations. For more complex cases, you can use native JavaScript animations or an external library such as GSAP or anime.js.

Consult the author or an expert on this topic.
Schedule a call
Filip Defar's profile image
Filip Defar

Located in Zagreb, Croatia

Member since May 12, 2014

About the author

Filip is a web developer with expertise in highly interactive front-end applications. He helped build data visualizations for several BI products while working for companies such as AlignAlytics and Captario.

Toptalauthors are vetted experts in their fields and write on topics in which they have demonstrated experience. All of our content is peer reviewed and validated by Toptal experts in the same field.

Years of Experience

10

World-class articles, delivered weekly.

Subscription implies consent to our privacy policy

World-class articles, delivered weekly.

Subscription implies consent to our privacy policy

Toptal Developers

Join the Toptal® community.