apike.ca

Text in SVG (text, tspan, tref)

By mbystedt on Feb 28, 2014, 11:41:44 PM

Text in SVG is rendered like all other graphical elements in SVG. All of the same stroking, filling, transformation, clipping and masking features of SVG you can do with a rectangle or circle can be done with text. Besides all the unique positioning attributes, the characters in a text element are really just treated like complicated shapes. See Text in SVG (Font, Anchor, Alignment) for how to alter the typography of text.

SVG has no layout features for text. This means there is no word wrap or text backgrounds like there is in HTML.

SVG provides attributes for placing the characters in the text in arbitrary positions and rotations. In any case, individually rotating characters is not something you normally need to do. So, the important attributes are just x and y. As you might imagine, placing characters on a curve or line rather than all over the place is the logical extension of this. There is an example of this in the path section.

The 'text' Element

<text x="50%" y="50%," dx="0,0,0,0,20" dy="0,0,0,0,8" rotate="20,30,40,50,0,0,-10" textLength="..." lengthAdjust="..." font-size="30" text-anchor="middle"><![CDATA[Hello World]]></text>
Code 1. The Text tag. Enclosing the text in a CDATA section avoids problems with brackets and other special characters in XML.
<text>
Attribute
Explanation
x
A list of x-axis positions. The nth x-axis position is given to the nth character in the text. If there are additional characters after the positions run out they are placed after the last character. (0 default)
y
A list of y-axis positions. See 'x' description. (0 default)
dx
A list of lengths which moves the characters relative to the absolute position of the last glyph drawn. (see x)
dy
A list of lengths which moves the characters relative to the absolute position of the last glyph drawn. (see x)
rotate
A list of rotations. The nth rotation is performed on the nth character. Additional characters are NOT given the last rotation value.
textLength
A target length for the text that the SVG viewer will attempt to display the text between by adjusting the spacing and/or the glyphs. (default: The text's normal length)
lengthAdjust
Tells the viewer what to adjust to try to accomplish rendering the text if the length is specified. The two values are 'spacing' and 'spacingAndGlyphs'.
Presentation Attributes
Example 1. Shows a modified version of Code 1. The text's characters have been individually rotated and moved. (Download)

Word Wrap

SVG 1.1 has no internal support for word wrap. In order to achieve this effect in native SVG it is necessary to break the lines apart manually. You could use a separate text tag for each line but using a single text tag and a tspan tag for each line is better because users can then select the text across lines. The third (and not recommended) solution works be embedding an XHTML document inside the SVG using a foreignObject tag. Rendering XHTML is not a requirement for SVG viewers so it may not work.

The 'tspan' element

The tspan tag is identical to the text tag but can be nested inside text tags and inside itself. Coupled with the dy attribute this allows the illusion of word wrap in SVG 1.1. Note that dy is relative to the last glyph (character) drawn.

S V G Hello World Today we are going to pretend that we are word wrapping around this rectangle. Isn't SVG's lack of word wrap completely annoying?
Example 2. Illusionary word wrap... It's better than nothing. (Download)

The 'tref' Element

This element references another text element in the SVG document and inserts the contained text. Only the character data is used and all presentation attributes and child tags (like 'tspan') of the referenced text are ignored. A limitation is that the text must come from within the same document.

<tref>
Attribute
Explanation
...
All attributes except the below are identical to the 'text' element.
xlink:href
Reference to a 'text' element.
Text Reference Attributes
<defs>
    <text id="helloWorld" ><![CDATA[Hello World]]></text>
</defs>
 
<text x="50%" y="50%" fill="blue" font-size="30" text-anchor="middle">
  <tref xlink:href="#helloWorld"/>
</text>
Code 2. Referencing the text allows it to be in the definition section.
Related Topics