How To Manipulate SVG Text

Last week I showed you how to create SVG text using the <text> element. In the examples I added x and y coordinates to position the text and the individual characters in a string of SVG text. There’s more to the <text> element.

You aren’t limited to the values of x and y attributes when working with SVG text. There are a few more attributes you can add to the <text> element and I’d like to talk abut them today.

The dx and dy Attributes

Let’s start with the dx and dy attributes which are similar to x and y, except each represents a length relative to the previous character instead of an absolute position relative to the viewport.

Just like x and y, dx and dy take a list of lengths instead of a single length, though you can set a list of one length.

Let’s pick up the example from last week and work in some values for dx and dy.

1
2
3
<svg width="660" height="220" style="outline: 1px solid red; overflow: visible;">  
  <text x="0" y="0" dx="10,20,30,40,60" dy="10,20,30,40,50,60">This is some SVG Text</text>  
</svg>

Here I set both x and y to 0 and then used a list of lengths on dx and dy. Notice as the value increases, the distance to the next character also increases. If you want the same space between characters you want to give dx and dy the same value as the previous value in the list.

This is some SVG Text

One thing you may or may not have noticed is the lengths and the spacings between characters don’t quite add up in the list above. If you map each length to a character, you would expect the “i” and “s” in “is” to be separated by 60px, which is the last value set.

The reason they aren’t, is because those 60px separate the “i” from the space between the the words “This” and “is.” Spaces count as characters.

Rotating SVG Characters

You can also rotate characters using the rotate attribute, which takes a list of numbers. Each number again represents a specific character.

1
2
3
<svg width="660" height="220" style="outline: 1px solid red; overflow: visible;">  
  <text x="0" y="20" rotate="0,45,0,90,180,0">This is some SVG Text</text>  
</svg>

Here I left x and y at 0 and added a list of numbers to the rotate attribute. The “T” will be rotated 0 degrees, the “H” will be rotated 45 degrees, and so on until we reach the end of the list and all remaining characters will be rotated 0 degrees.

This is some SVG Text

Similar to the previous example, spaces count. Here the space between “This” and “is” is being rotated 180 degrees, which is why I added a 0 to the end of the list. Otherwise the rest of the characters would also be rotated 180 degrees and be upside down.

Again it’s the individual characters that are being rotated and not the entire string of text. To rotate the entire string you would use a transform.

The textLength Attribute

The next attribute you can add is textLength which takes a single length as a value.

The textLength attribute lets you set the length of the text to a specific amount regardless of the size of the container.

1
2
3
<svg width="660" height="220" style="outline: 1px solid red; overflow: visible;">  
  <text x="0" y="20" textLength="660">This is some SVG Text</text>  
</svg>

Here I set textLength to the same width as the viewport so the text stretches from end to end. Note that the last character doesn’t touch the right edge. That’s because it’s still inside an EM box. The right edge of the EM box is what touches the right edge of the viewport.

Note: As mentioned by Šime in the comments, the last character does touch the right edge in Firefox and Edge browsers. I’m guessing it’s to do with how each browsers calculates the spacing between characters, but I’m not sure. If anyone knows, please share in the comments below.

This is some SVG Text

The characters are automatically spaced out so the text string fills the space. It’s like justifying the content, except you can set the width on the fly.

You can also squish the characters together if you’d like, by setting a length smaller than what’s necessary to display them all.

1
2
3
<svg width="660" height="220" style="outline: 1px solid red; overflow: visible;">  
  <text x="0" y="20" textLength="50">This is some SVG Text</text>  
</svg>

This is some SVG Text

Naturally this isn’t advisable with text you want people to read, but it could be used to create some interesting effects when the text doesn’t need to be read.

One thing you may have noticed is that it was the space between characters that was adjusted with textLength, but the characters themselves remained the same size. You can change that with the last attribute specific to the textElement.

The lengthAdjust Attribute

The lengthAdjust attribute takes two values (spacing or spacingAndGlyphs), which determine what gets stretched or squished.

Of the two values, spacing is the default, which is why the previous examples used the space between characters to adjust to the the length specified. Here’s a previous example with a change to lengthAdjust.

1
2
3
<svg width="660" height="220" style="outline: 1px solid red; overflow: visible;">  
  <text x="0" y="20" textLength="660" lengthAdjust="spacingAndGlyphs">This is some SVG Text</text>  
</svg>

The characters are now being stretched in addition to the spaces between them.

This is some SVG Text

I mentioned earlier that because SVG text is rendered as a graphic element that you can apply things like strokes and fills , patterns and gradients. Any attribute you can add to SVG elements in general can also be applied to SVG text.

To prove that, here’s an example where I’ve changed the fill to blue, added a red stroke, and doubled the stroke-width to 2.

1
2
3
<svg width="660" height="220" style="outline: 1px solid red; overflow: visible; font-size: 5em;">  
  <text x="240" y="120" stroke="red" stroke-width="2" fill="blue">SVG</text>  
</svg>

SVG

Between this and the last post, I’ve shown quite a few ways to manipulate text and we still have more text related elements to get to. Let’s stop here today, though.

Closing Thoughts

I hope you agree that SVG text is relatively easy to work with. Instead of a <rect> or a <circle> you create a <text> element inside your <svg> element, which is then rendered as a graphic with text that can be search and selected.

Even limiting ourselves to the attributes of the <text> element we can manipulate SVG text in a number of useful ways.

Next week I’ll pick things up with the <tspan> element, which will allow you to style parts of your SVG text differently. The following week I’ll show you to use the <tref> element, which allows you to reuse text across different <svg> elements.

Download a free sample from my book, Design Fundamentals.

2 comments

    • Thanks Šime. Funny. I had a feeling you’d comment and find something I missed. I don’t have Edge installed, but I checked Firefox and you’re right, the last letter touches the right edge.

      I guess it’s something to be aware of. Different browsers treat some of this stuff differently. Something we should all be used to by now.

      I can’t find a reason why browsers would display textLength differently, but I’ll make a note in the post and keep searching for a reason.

      Thanks as always for letting me know.

Leave a Reply

Your email address will not be published. Required fields are marked *