Published at
Updated at
Reading time
2min
This post is part of my Today I learned series in which I share all my web development learnings.

You've probably seen this SVG effect that people use to animate signatures. If you have an SVG path you can combine stroke-dasharray, stroke-dashoffset and CSS animations/transitions to animate a given SVG path. Here's an example of the effect.

Hover the image to trigger the animation.

The SVG includes a single SVG path that expands when you hover over the SVG. How does this work in detail?

As a first step, you can cut SVG paths into visual pieces with stroke-dasharray. It's important to know that the "drawn pieces" and in-between gaps will have the same length.

Then, after you've chopped your path into pieces, you can move these pieces around the SVG path with stroke-dashoffset.

So, the overall trick is to make the pieces as big as the entire path length to transition from showing a gap (which spans the entire path) to showing a drawn piece next to it.

path {
  stroke-dasharray: 0;
  stroke-dashoffset: 0;
}

If you played with the demo above, you might have wondered where this magic number (14302) is coming from. 14302 is the overall path length, and you can access it with some JavaScript.

const path = document.querySelector('path');
const pathLength = path.getTotalLength();

With the path length available, you can then write some quick CSS to achieve this effect.

path {
  /* Cut the path into pieces being as long as the path itself */
  stroke-dasharray: 14301;
  /* Move the rendering to the gap */
  stroke-dashoffset: 14301;
  transition: stroke-dashoffset 0.75s ease-in-out;
  
  &:hover {
    /* Transition the offset to show the rendered path piece */
    stroke-dashoffset: 0;
  }
}

And while this approach works just fine, it's a bit cumbersome to always figure out the path length. After reading Josh's wonderful article A Friendly Introduction to SVG, I learned that you can set the path length manually in your SVG using the pathLength attribute!

<svg width="7149" height="1392" viewBox="0 0 7149 1400">
  <path d="M0.640625 ..." pathLength="100" />
</svg>

And with this tiny adjustment, the CSS animation becomes way easier to handle because you can base your animations on the path length of 100.

path {
  /* Cut the path into pieces being as long as the path itself */
  stroke-dasharray: 100;
  /* Move the rendering to the gap */
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 0.75s ease-in-out;
  
  &:hover {
    /* Transition the offset to show the rendered path piece */
    stroke-dashoffset: 0;
  }
}

Isn't this way nicer? I'm a fan!

If you enjoyed this article...

Join 6.1k readers and learn something new every week with Web Weekly.

Web Weekly — Your friendly Web Dev newsletter
Reply to this post and share your thoughts via good old email.
Stefan standing in the park in front of a green background

About Stefan Judis

Frontend nerd with over ten years of experience, freelance dev, "Today I Learned" blogger, conference speaker, and Open Source maintainer.

Related Topics

Related Articles