Sign on the Dotted Line: Animating Your Own SVG Signature

Animating the stroke of an SVG is perfect for simulating handwriting. Over the course of two tutorials we’re going to use CSS animation to make a signature neatly appear to be written, as though you’re signing the page yourself.

Here’s what we’ll be building:

1. SVG File

Before we dive into any code, we’re going to need an SVG version of your signature. It doesn’t matter what software you use to make this, but try to keep the lines and curves as smooth as possible for best effect.

Here’s mine, which you can see is drawn with three separate paths:

first signature path

First path
Second signature path

Second path
Third signature path

Third path

Make sure your artboard is cropped tightly to the signature, then save the file as an SVG.

2. Tidying the SVG Code

Opening the file in a code editor will reveal the SVG’s XML structure. Depending on which application you used to design it, plus how you saved or exported it, you’ll have an <svg> element with some mumbo jumbo before it. The mumbo jumbo can be removed.

In this case, the elements we’re left with look something like:

Within our main <svg> we have a <line>, then a <path>, then another <line>. These are the three vectors we drew, differentiated only because, technically, a line has no curvature, so it’s defined differently to a path in SVG.

3. Add Classes

We’ll need to separately target these vectors with CSS a little later on, so make sure they each have a suitable class name. The <svg> element will likely already have an id reflecting the layer name in the application it was designed with.

I’ve given my vectors class names depending on what they are (the first one is the “I” in my name, for example).

4. All the Other SVG Attributes

In fairness, your SVG won’t be looking quite this neat. Each of these vectors will have a load of coordinates, plus several attributes buried within them. The coordinates will need to stay, but we can remove some of the commonly-used attributes and place those in our CSS instead, keeping things nice and DRY.

New Project

I’m going to build this using CodePen, but you can use standalone HTML and CSS documents if you prefer. Paste the SVG code directly into your HTML document. Then, remove the attributes each of the path and line elements have in common, placing them instead in the CSS document. For example, you’ll notice attributes like:

  • fill="none"
  • stroke="#0F436D"
  • stroke-width="2"
  • stroke-linecap="round"
  • stroke-linejoin="round"
  • stroke-miterlimit="10"

These can be removed and applied via CSS instead, like so:

Much cleaner!

5. Begin Animating

In order to animate the strokes of this SVG we’re going to be using a technique first discussed by Jake Archibald. The idea is as follows: each of these vectors is going to be given a dashed stroke. We do this by applying a stroke-dasharray value within the CSS:

Dash Length

For each of these vectors we make the stroke-dasharray precisely the length of the path, so each one has a single dash covering its entire length. This takes a bit of trial and error, but in our case the values look look like this:

Now, in order to animate these strokes, we need to offset each of the dashes so that the gap covers the vector, not the dash. Does that make sense? These illustrations might help. In this first one, imagine the dashed line is being used to cover the flourish at the end of the signature.

Now in this one we’ve offset the dash, so it’s the gap which is over the flourish:

Now all we need to do is use CSS to animate from the offset state to the other.

6. Keyframes

CSS animation relies on first defining keyframes. Each keyframe represents states along a timeline, then our browsers render the animations between them.

Let’s first see how this dash offset can be animated. We’ll use the first stroke, the “I”, and animate between two states. Begin by setting up some keyframes:

Here we give the keyframes a name (write1) and using shorthand syntax specify that at the very beginning of the timeline (0%) we want the stroke-dashoffset to be 80. In other words: the dash, which is exactly 80px long, will be offset completely.

At the end of the timeline (at 100%) we want the stroke-dashoffset to be 0, so the dash is once more covering the vector.

Apply Animation

Now we have our keyframes, let’s attach them to an animation. We add another declaration to our stroke-I rule:

Here, using the animation property, we say that we want to use the write1 keyframes defined a moment ago, we want the whole thing to last exactly 3 seconds, we want the animation to loop infinitely and we want the speed to be linear (so that there’s no acceleration or deceleration).

Here’s what we get:

Note: I’m using Autoprefixer in CodePen which saves me having to use browser prefixes on the animation stuff.

Apply to All Three Vectors

We need to define two more sets of keyframes (write2 and write3) for the remaining vectors in the signature–and we need to offset by the correct dash lengths we discovered earlier:

Then we need to apply those animations to the remaining two vectors:

Here’s what we get:

Now we’re getting somewhere! Each vector is animating perfectly, in a linear motion lasting 3 seconds.

Next step? To get them animating in sequence.

7. Sequential Animation

Currently we have three strokes all animating simultaneously. However, we ideally want the “I” to animate, then the “an”, then finally the flourish at the end. If we were to visualise that along a timeline it might look like this:

We can actually represent these sections of the timeline perfectly in our CSS keyframes. For example, the first section (from 0% to 33.3%) is when we want our “I” to animate, so we alter the keyframes to finish at 33.3% instead of 100%:

Now, given that all three of our animations are the same length (3 seconds) we can make sure the second doesn’t start until 33.3%, when the first animation is complete:

Here’s what that gives us:

Completing the Sequence

The first two animations flow nicely, so let’s improve things by getting the second to finish at 66.6%, at which point the final animation can start. Our keyframes will look like this:

And the sequence will look like this:

Further Refinement

What we have is good, but it isn’t perfect–certainly far from a realistic pen movement. Each of these three vectors is being drawn over the course of one second, irrespective of its length. The middle vector is wa-ay longer than the last, so it should logically take longer to draw. A better timeline might look something like this:

For added realism there’s even a gap between the first vector finishing and the second beginning. So let’s alter our keyframe values to reflect that:

Finally, let’s speed things up by changing all the 3s values to 2s. We can also update the animation declarations so that each one runs just once, not infinitely looping:

You might also want to play with the linear value, instead adding some easing such as ease-in, ease-in-out, ease-out etc. to make the movement less uniform. What does that all give us?

Next Time

We’ve made great progress and learned a lot along the way! In the next tutorial we’ll take things a step further, using Waypoints.js to help us control when the animation takes place. I’ll see you there!