A price line where only the final amount should stand out in green, a heading where one specific word changes colour mid-line: impossible with a single <text> element, which only knows one colour and one size for its whole content. That is the job of <tspan>, splitting that line into independently styled pieces.
Without it, styling a single word inside an SVG sentence would mean cutting the sentence into several separate <text> elements, with the position of each one worked out by hand.
Definition
<tspan> marks off a portion of text inside a <text> element, or inside another <tspan>, to apply a different position or style to it without breaking the visual flow of the text. It has no life outside its parent: on its own, outside a <text>, it simply does not render.
Main attributes
| Attribute | Role |
|---|---|
x, y | Repositions the tspan to an absolute coordinate |
dx, dy | Shifts the tspan relative to the text's current position |
fill | Changes the colour of that portion only |
font-weight | Changes the weight of that portion only, for example to bold a single word |
Without x or y set, a <tspan> simply carries on where the previous text left off: that behaviour is what lets a single word change colour without breaking the alignment of the rest of the sentence.
Concrete rendering example
Here is a sentence where only the word "free" changes colour, thanks to a tspan with no repositioning at all.
<svg viewBox="0 0 260 60" xmlns="http://www.w3.org/2000/svg">
<text x="10" y="35" font-size="18" font-family="sans-serif" fill="#1e293b">
Shipping is
<tspan fill="#16a34a" font-weight="bold">free</tspan>
over $50
</text>
</svg>The "free" tspan inherits the position and size of the parent text, only its colour and weight change: the rest of the sentence keeps flowing normally around it.
Difference with <text>
<text> is a standalone element, able to exist on its own inside an SVG. <tspan> is not: it is an internal splitting tool, meant to live inside a <text> element. Several tspans can nest inside one another, but never outside an enclosing text.
Classic trap: placing a <tspan> directly in the SVG, without nesting it inside a <text> element, triggers no visible error, but the tspan simply does not render. It is one of the hardest "missing text" bugs to spot, because the code looks correct on first read.
Real-world use case
Tspans are used to build multi-line text by hand inside an SVG chart, one tspan per line with an increasing y, to highlight a key figure inside a caption, or to show a unit in a smaller size after a numeric value, like "12" followed by a smaller "kg". Combined with <textPath>, a tspan can even make a single word stand out within text that follows a curve.
As with <text>, a tspan's content stays real text: coloured words remain selectable with the mouse and readable by assistive technology, unlike an image where each styled word would have been cut out and exported by hand.
Frequently asked questions
tspan be nested inside another tspan?Yes, a tspan can contain other tspans, which allows styling a sub-portion of a word that is already styled. That kind of nesting stays rare in practice, reserved for very fine-grained formatting.
tspan change the font being used?Yes, every text presentation attribute such as font-family, font-size or font-style can be redefined on a tspan, exactly as on the <text> element that contains it.
tspan with x and y show up somewhere unexpected?Because x and y on a tspan reposition the text absolutely, onto a new baseline, while dx and dy only shift it relative to the current position. Mixing the two up sends the text jumping to an unexpected spot in the SVG.