Text Along a Path on the Web Using SVG textPath

I’m working on a new side project called 🌀 Spiral11, and with the theme of spirals I became interested in playing with text on a path effects. I was happy to see that SVG has a native element, textPath, to accomplish exactly that without having to resolve to using an image instead. That means we get to keep all the good things we’re used to with text on the web, like the ability to select it or for screen readers to read it or even the ability to have links as part of the text.

Plus, as you’ll see, it’s really easy to accomplish. Let’s go over how it’s done.

To whet your appetite, here’s what the final effect looks like, full with a clickable link and all:

See you later, Alligator! 🐊 No so soon, Baboon! 🐵

With this, the text is following an SVG path that I’ve simply drawn using the vector tool in Sketch, which looks like this:

And here’s the markup for this path:

<svg viewBox="0 0 1160 262" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto;">
  <path stroke="#979797" stroke-width="3" fill="none" d="M0.05078125,107.609375 L237.603724,72.0980293 C257.310784,69.1520578 277.448615,72.1606986 295.434067,80.7380223 L440.117791,149.73819 C461.666904,160.015036 486.181718,162.243221 509.230549,156.019944 L856.599391,62.2289545 C883.145646,55.0613586 911.471983,59.140881 934.916817,73.508129 L1160.05078,211.472656 L1160.05078,211.472656"></path>
</svg>

To start turning it into a path that’s used for text to follow, we’ll stick our path definition in an SVG <defs> element and give it an id:

<svg viewBox="0 0 1160 262" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <path id="path-1" fill="none" d="M0.05078125,107.609375..."></path>
  </defs>
</svg>

I’ve removed the stroke from the path so that the path itself wouldn’t be visible, but you could just as well still have the path showing.

Enter text and textPath

Now the fun part starts when we use the SVG <text> element with a <textPath> inside, and point such <textPath> to our path via its id:

<svg viewBox="0 0 1160 262" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto;">
  <defs>
    <path id="path-1"  fill="none" d="M0.05078125,107.609375..."></path>
  </defs>

  <text style="fill: var(--text-color);">
    <textPath xlink:href="#path-1">
      See you later, Alligator! 🐊 No so soon, Baboon! 🐵
    </textPath>
  </text>
</svg>
See you later, Alligator! 🐊 No so soon, Baboon! 🐵

I’ve set the text color here using CSS variables.

Centering with text-anchor & startOffset

It’s a good start, except our text is a little small and it would be nice if somehow there was a way to center the text on the path:

<svg viewBox="0 0 1160 262" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <path id="path-1" d="M0.05078125,107.609375..."></path>
  </defs>

  <text text-anchor="middle" style="fill: var(--text-color); font-size: 3rem;">
    <textPath xlink:href="#path-1" startOffset="50%">
      See you later, Alligator! 🐊 No so soon, Baboon! 🐵
    </textPath>
  </text>
</svg>

As you can see, the trick to center our textPath content is to set its startOffset to 50% and then set the text-anchor attribute on the text element to a value of middle.

You'll want to be careful with the size you set the text at. I've noticed that large text can end up being clipped if it doesn't fit inside the SVG viewbox. Setting the CSS overflow property to a value of visible can of course come in handy here.

Which side are you on?

There’s an attribute, side, which defaults to a value of left to specify on which side of the path (left or right) the text should be drawn, except at the time of this writing the attribute is only supported in Firefox.

Anchors

<textPath> can contain anchor elements:

<svg viewBox="0 0 1160 262" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <!-- ... -->

  <text text-anchor="middle" style="fill: var(--text-color); font-size: 3rem;">
    <textPath xlink:href="#path-1" startOffset="50%">
      See you later, <a xlink:href="https://alligator.io/">Alligator</a>! 🐊 No so soon, Baboon! 🐵
    </textPath>
  </text>
</svg>

Final Markup

Here’s the full markup of our example, for your reference, and I encourage you to have a look at the MDN reference for textPath if you want to learn about all the potential attributes it can take:

<svg viewBox="0 0 1160 262" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <path id="path-1" d="M0.05078125,107.609375 L237.603724,72.0980293 C257.310784,69.1520578 277.448615,72.1606986 295.434067,80.7380223 L440.117791,149.73819 C461.666904,160.015036 486.181718,162.243221 509.230549,156.019944 L856.599391,62.2289545 C883.145646,55.0613586 911.471983,59.140881 934.916817,73.508129 L1160.05078,211.472656 L1160.05078,211.472656"></path>
  </defs>

  <text text-anchor="middle" style="fill: var(--text-color); font-size: 3rem;">
    <textPath xlink:href="#path-1" startOffset="50%">
      See you later, <a xlink:href="https://alligator.io/">Alligator</a>! 🐊 No so soon, Baboon! 🐵
    </textPath>
  </text>
</svg>
That's it for now. Have fun with SVGs! ✨
  Tweet It

🕵 Search Results

🔎 Searching...