Bryan Rasmussen Nowadays, I typically focus on JavaScript-intensive projects, React frontend work, accessibility, Node.js backends, ElasticSearch, and automation. I'm also proficient in documentation and technical writing.

Animation tricks with SVG z-index

4 min read 1323

Animation Tricks With SVG Z-index

As an entertainment medium, the web requires a judicious use of special effects to catch and hold interest. In contrast to other media formats, however, the web is limited by bandwidth. If we can find ways to make interesting effects with less data sent over the wire, we all win.

In this article, I’m going to talk about techniques to do more with some simple SVG tricks. In the interest of brevity, I shall assume readers have a rudimentary knowledge of SVG, so I will not explain the more basic concepts.

At the same time, to keep the code more easily understandable, I’ll avoid various optimizations so that I don’t have to explain them. This means the code will at times be more verbose than necessary, but recognize the verbosity is in the service of clarity.

Z-indexing in SVG

The following snippet of SVG code represents a circle:

<circle  cx="50" cy="50" r="25" fill="#ff0000" />

As do these:

<circle  cx="50" cy="50" r="25" fill="#ffff00" />
<circle  cx="50" cy="50" r="25" fill="#ffffff" />

If you have the first two circles in an SVG, you will see a single yellow circle. If you have all three, you should see nothing — assuming the SVG they are in is white.

See the Pen
Layered Circles
by Bryan Rasmussen (@bryanrasmussen)
on CodePen.

The reason for this is SVG’s z-indexing rules, which dictate that when any two graphical elements occupy the same space, the one represented later in the XML tree that the SVG is described by will be given a higher z-index. The white circle is at the same position as the yellow and covers it precisely.

The r attribute on each circle represents its radius. Thus, if you want to have layered circles where you can see the circles underneath, you might do so by increasing the radius, like so:

We made a custom demo for .
No really. Click here to check it out.

See the Pen
Layered Circles Visible
by Bryan Rasmussen (@bryanrasmussen)
on CodePen.

If you did not have the white circle, it would look like you had a yellow circle with a thick red border or stroke. The same principle applies to other graphical elements in SVG.

Let’s suppose we put the following rectangle in between the white and yellow circle.

<rect x="25" y="25" width="50" height="50" fill="#ff00ff" />

Notice the x and y are half the cx and cy of the circle — because circles are drawn from the center out, and rectangles are drawn from the top left. It will look like this:

See the Pen
Layered Circles And Rects Visible
by Bryan Rasmussen (@bryanrasmussen)
on CodePen.

And finally, I will put another rectangle in between our previous rectangle and the white circle and rotate it to make a simple star shape:

<rect x="25" y="25" width="50" height="50" fill="#ff00ff" transform = "rotate(45 50 50)"/>

The 50 values represent the center of the rectangle, which is, of course, the same value as the cx and cy of our circle.

See the Pen
Layered Circles And Rects 2
by Bryan Rasmussen (@bryanrasmussen)
on CodePen.


I think at this point we have enough little areas to play with that we can see about making some interesting effects with animation.


One of the easiest ways to animate things in SVG is to use animateTransform, which animates a transformation attribute on its target element. In other words, if I put an animateTransform element as a child of one of these rectangles, I can animate the transform attribute, which we used in our earlier example to rotate our last rect.

If we add the following animateTransform as the child of the last rectangle…

    from="0 50 50"
    to="360 50 50"
    repeatCount="indefinite" />

…we will cause that rectangle to rotate a full 360 degrees every 10 seconds indefinitely.

The first number of the from attribute is from how many degrees it should be rotated at the start of the animation; the first number of the to is how many degrees it should be rotated at the end of the animation. And if we are doing this, we can remove the original transform attribute on the rectangle, as it is rendered redundantly. Like so:

See the Pen
Layered Circles And Rects 2 Animated
by Bryan Rasmussen (@bryanrasmussen)
on CodePen.


animate allows you to animate less complicated attributes than the transform attribute, but in the same manner.

As an example, let’s add the following animate element as the child of our rectangle that has the animateTransform:

    values="#ff0000; #ffff00; #ff00ff;" 

Visible here:

See the Pen
Layered Circles And Rects 2 Animated 2
by Bryan Rasmussen (@bryanrasmussen)
on CodePen.

As an example of how the other properties of the animation — like its duration and the number of times to repeat it — can create interesting effects, take a look at this layering of circles.

Each circle has a different duration of animating the fill, the number of times it repeats is set so that they should stop at different times — all except the inner circle, the last in the XML tree, which should have its fill animated forever.

See the Pen
Layered Circles animate fills in sequence
by Bryan Rasmussen (@bryanrasmussen)
on CodePen.

As for how you can animate other SVG properties, the following example animates the cx property of a number of layered circles. The duration is off by a bit for each one, and the starting time is such that the bottom layer starts first, the top layer starts last, and they all finish one after the other.

The fill property is set to freeze on the animation, which means the attribute will end up with the value that ends the animation (in this case, 250).

See the Pen
Layered Circles animated cx in sequence
by Bryan Rasmussen (@bryanrasmussen)
on CodePen.

One last thing to note about these animations is that transparent is a color — this fact will be of use in the next section.

Layering and timing animations

Look at the following animation:

See the Pen
Layered Circles animated cx with stop points and images
by Bryan Rasmussen (@bryanrasmussen)
on CodePen.

What’s happening here is that there are 18 circles in the SVG. Twelve of the circles are placed along the length of the SVG in pairs — that is to say, there are two circles at cx="100" on the x radius, two circles at cx="200", and so forth. Here is the code for the first pair of circles:

  <circle  cx="100" cy="50" r="30" fill="url(#image1)"></circle>
  <circle  cx="100" cy="50" r="30" fill="#ffffff">
      values="#ffffff;transparent; " 

Because these two circles sit in the same place, the one that comes later in the markup tree has the higher z-index. So the circle with a fill color of white sits on top of a circle that is filled by an image.

But that white-colored circle has an animation that makes it transparent, meaning you can see the image in the circle underneath when the animation is finished.

Finally, there are six circles that start off at the same location — cx="50", cy="50" — and are animated along their cx. Each one of these circles stops somewhere, covering one of the white circles that, in turn, cover the circle with an image in it.

The white circle animations start after the six circles are done moving to their respective cx positions. Then, the six circles have an animation on their fill to move from either yellow or red to transparent. Of course, when they are done animating, the white circles are already done animating; therefore, we see the circles with images in them after the fill color of the top image becomes transparent.


In conclusion, with SVG’s z-indexing and properly timed animations, it is pretty simple to construct advanced effects through simple markup patterns that catch the user’s attention.

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

    Which of these topics are you most interested in?
    ReactVueAngularNew frameworks
    Do you spend a lot of time reproducing errors in your apps?
    Which, if any, do you think would help you reproduce errors more effectively?
    A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
    Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

    : Full visibility into your web apps

    LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

    In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

    Bryan Rasmussen Nowadays, I typically focus on JavaScript-intensive projects, React frontend work, accessibility, Node.js backends, ElasticSearch, and automation. I'm also proficient in documentation and technical writing.

    Leave a Reply