Grow your CSS skills. Land your dream job.

How SVG Line Animation Works

Published by Chris Coyier

I bet all of you have seen that little trick where an SVG path is animated to look like it's drawing itself. It's super cool. Jake Archibald pioneered the technique and has a super good interactive blog post on how it works. Brian Suda wrote about it on 24 Ways. Polygon used it to great effect on a custom designed article and wrote about it. Codrops has some neat examples.

I have very little to add, except my brain just kinda figured it out, so I thought I would explain it one more time the way it clicked for me.

1. You have an SVG shape

2. The shape must have a stroke

3. Strokes can be dashed

We could do that from Illustrator, but we can also do it programatically. Let's target the path with CSS (assuming we're using inline SVG here, or via an <object>) and apply the dash that way.

<svg ...>
  <path class="path" stroke="#000000" ... >
</svg>
.path {
  stroke-dasharray: 20;
}

That gives us dashes of 20px in length.

4. Those dashes could be longer...

.path {
  stroke-dasharray: 100;
}

5. We can also "offset" the stroke, which moves the position of those dashes

Watch as we animate the offset of those long strokes:

That was a simple as:

.path {
  stroke-dasharray: 100;
  animation: dash 5s linear;
}

@keyframes dash {
  to {
    stroke-dashoffset: 1000;
  }
}

6. Imagine a dash so long it covers the entire shape

Nothing really to see, it looks just like the complete shape if it wasn't dashed at all. You just need to make stroke-dasharray a longer value than the length of the stroke.

7. Now offset that stroke so that instead of covering the entire shape, it NOT covers the entire shape.

It will look like the shape isn't there at all.

8. Now animate the stroke offset back to 0

If doing it with CSS, you'll want the animation to have animation-fill-mode of forwards so the final state remains how the animation ends.

.path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: dash 5s linear forwards;
}

@keyframes dash {
  to {
    stroke-dashoffset: 0;
  }
}

Tada!

Live Example

See the Pen bGyoz by Chris Coyier (@chriscoyier) on CodePen.

So why all the JavaScript?

Most of the examples you see of SVG line animations use JavaScript. That's because it's hard to know what the length of that stroke actually is. We just used 1000 in our example because that happens to be about the right length.

You can get that length in JavaScript like:

var path = document.querySelector('.path');
var length = path.getTotalLength();

Then use it however you will. Those articles I linked to at the top go far more into all this, so I'll let you consult those for more fancy stuff. I just wanted to cover the concept so perhaps it can click for you too.


Wanna learn more about SVG?

I have a full course available called Everything You Need to Know about SVG that covers the whole spectrum of SVG from the perspective of a web designer and front end developer.

Comments

  1. Great article, thanks for this!

  2. Martijn
    Permalink to comment#

    Bravo!
    As always, using properties for effects they were never intended for :)

  3. Nick Spiel
    Permalink to comment#

    Totally sweet. Such a simple method that could be used to produce some great effects!

  4. MaxArt
    Permalink to comment#

    Very cool, but alas, no Internet Explorer support. Not even IE11.

    • Permalink to comment#

      Then no SVG animations for IE. Create a fallback solution!

    • Jeff Harris
      Permalink to comment#

      I’ve found the only way to get good cross browser support was using Javascript to animate for IE9 and greater. Here’s a good reference to get started -> Animating SVGs

    • Levi

      I also found that this doesn’t work in IE. Snap.svg is a pretty great alternative. All the techniques and basic theory here hold true; you create a path with a given length, and then set strokeDasharray and strokeDashoffset to the same length. Then you can just do path.animate({strokeDashoffset: 0}, 1000); for the same effect (1000 is time in ms).

  5. Permalink to comment#

    Very nice! I made an experiment using it. But to work in chrome I had to add @-webkit-keyframes and -webkit-animation.

    You can see it here.

  6. Rene Ruiz
    Permalink to comment#

    I’m having trouble understanding this part:

    “Now offset that stroke so that instead of covering the entire shape, it NOT covers the entire shape.”

    If you make the dash array equal to the length of the stroke, why does offsetting it make it begin to disappear where does the rest of it go?

    • Yeah that is weird. I guess it’s because when you do the dash thing, there always has to be at least one dash and one gap of equal length. So depending on where that dash or gap line up, is what portion of the stroke appears to be filled in.

  7. abhishek
    Permalink to comment#

    Hello Chris

    I was just playing around the code and when I run it my system (after copy pasting the code) i was not able to get any output on the screen.

    but what added more to my surprise was that it runs smoothly on code pen but not on jsbin or js fiddle.

    (http://jsfiddle.net/65LzR/ “fiddle”)

    please delivery your views on it

    browser used : chrome 32

  8. Awesome tutorial, thank you for sharing.

  9. Joe_Temp
    Permalink to comment#

    That’s awesome!

  10. Conrad
    Permalink to comment#

    This is great! Thanks. Do you have any resources/docs for svg properties that can be animated using css (or even js, for example in combination with the amazing greensock animation library?.

  11. Doug Wollison
    Permalink to comment#

    This beats the hell out of what I’m currently using; the getSubpath() method in Raphael.js. It did the job, but often looked more like the stroke was being scaled up from its origin point.

  12. Permalink to comment#

    Hi!
    That’s very nice!!
    It works if I write the svg in html, but it doesn’t if I import the svg using the object:

    <object type="image/svg+xml" data="images/mappa.svg">
        Your browser does not support SVG
    </object>
    

    I can this be fixed?
    :*

    • Permalink to comment#

      If you hide your SVG in an <object> tag, it’s inaccessible from CSS. You could include the CSS styles inside the external SVG file, but I can’t guarantee that will work in all SVG browsers.

  13. Vheissu
    Permalink to comment#

    yay! great article, one question: how can I stop the animation once are finished?

  14. Sagi Shrieber
    Permalink to comment#

    Amazing! Thanks a lot for this quick and easy-to-understand explanation!

  15. JackHou
    Permalink to comment#

    Thanks a load! It’s really useful.

  16. Fatemeh
    Permalink to comment#

    Great ! :)

  17. Cody
    Permalink to comment#

    Yeah it makes for some pretty cool and easy animations especially if your designer loves vector and won’t work in anything except adobe illustrator.

  18. ChrisB
    Permalink to comment#

    You can get that length in JavaScript like: […]

    Will that value be “static”, meaning will it always be the same for the same given path? So that it would be enough to use JS once to get its length, and then one could put that fixed value into the CSS (yeah, I know, it’d be kind of a ”magic number”, but still).

    Or is it dynamic, depending on … what? Browser, display size of the SVG image, …?

    • The length is given in the coordinate system units for the path element, and therefore is independent of any scaling of the SVG as a whole. However, the specs allow browsers to guesstimate the exact length using an algorithm of their choosing, so the results might not always be exactly the same. To control for that, you can set the “pathLength” attribute on your path element to the value that you’re using for animations, and the browser is supposed to adjust its calculations accordingly.

      In other words, to ensure inter-operability you can use Javascript to figure out the length of your path on your development computer, and then declare that length in a pathLength attribute on the path element, and then safely use it in your CSS animations without worrying that things will be slightly off on a different browser. You could skip the calculation and just declare the pathLength to be a nice round number of your choosing, but then you’d want to do some in-depth cross-Browser testing to make sure they all make the appropriate calculations…

    • ChrisB
      Permalink to comment#

      Thanks Amelia, also for your other comment, quite useful!

  19. Elushi
    Permalink to comment#

    Hi,
    I recreated this and I would like after the animation is drawn to stay on the page. How would I go about that? I took out the infinite and it only plays once. I would like it to stay on the page.
    Any help would be great.
    Thanks!

    .path {
    stroke-dasharray: 1000;
    stroke-dashoffset: 1000;
    -webkit-animation: dash 5s linear;
    -webkit-animation-iteration-count:1;
    }

    @-webkit-keyframes dash {
    from {
    stroke-dashoffset: 1000;
    }
    to {
    stroke-dashoffset: 10;
    }
    }

  20. Permalink to comment#

    I don’t get it, why do you need stroke-dashoffset: 1000;?

    You can just do this:

    .path {
    stroke-dasharray: 1000;
    animation: dash 5s linear;
    animation-fill-mode: forwards;
    }

    @keyframes dash {
    from{
    stroke-dashoffset: 1000;
    }

    to {
    stroke-dashoffset: 0;
    }

    }

  21. Alex

    Some browsers support SVG but not the line animation (I’m looking at you IE).
    So how can I test if the browser supports SVG line animation, so I can fallback to a raster ?

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".