A confirmation badge, an interactive map with city names on it, a bar chart with its values printed above each column: whenever an SVG needs to carry a word or a number, <text> is what shows it. Without it, a vector drawing stays mute, however precise it is.
It is one of the most used elements in SVG, and yet one of the most misunderstood on the first try: its coordinates do not behave like those of an HTML box.
Definition
<text> displays a string of characters inside an SVG document. It accepts plain text between its opening and closing tags, much like an HTML paragraph, but its positioning and styling follow SVG rules rather than the usual CSS box model.
Without <text>, an SVG cannot display a single word: the other elements draw shapes, only this one writes.
Main attributes
Four attributes cover most real-world cases.
| Attribute | Role |
|---|---|
x, y | Position of the text's anchor point |
text-anchor | Alignment of the text relative to that point (start, middle, end) |
font-size | Font size, in pixels or SVG units |
fill | Text colour, not to be confused with color, which has no effect here |
That last point trips up a lot of SVG beginners: text colour is set with fill, the same property that colours a rectangle or a circle. The CSS property color has no effect on a <text> element.
Positioning text: the baseline, not the corner
In HTML, an element is most often positioned by its top-left corner. In SVG, x and y on <text> mark the starting point of the baseline, that invisible line letters appear to sit on, like on ruled paper. Letters rise above that point, and descenders on letters like "g" or "p" drop below it.
Classic trap: giving y the same value as the height of a nearby icon places the text too low, overflowing the visible frame, because y marks the baseline, not the top of the letters. It usually needs to be nudged up by roughly the font size for the text to stay inside its intended bounds.
Concrete rendering example
Here is a status badge with a checkmark icon and its label, centred under the icon with text-anchor="middle".
<svg viewBox="0 0 220 130" xmlns="http://www.w3.org/2000/svg">
<circle cx="110" cy="45" r="32" fill="#16a34a" />
<path
d="M95 46 l11 11 l22 -24"
stroke="#ffffff"
stroke-width="7"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
/>
<text
x="110"
y="104"
text-anchor="middle"
font-size="15"
font-family="sans-serif"
fill="#1e293b"
>
Payment confirmed
</text>
</svg>text-anchor="middle" centres each line of text on the given x coordinate, whatever its length: handy for centring a caption under a shape whose text width is not known in advance.
Difference with regular HTML text
An HTML paragraph flows, wraps to a new line on its own, and adapts to the width of its container. <text> does none of that: it sits on a single line, with no automatic wrapping, and overflows the viewBox if the string is too long. For longer text or a multi-line layout, either repeat <text> at different positions, or use <tspan> to create several lines inside a single block.
Another difference: the usual CSS properties such as padding, margin or line-height have no grip on <text>, which follows its own baseline geometry instead.
Real-world use case
On an interface like Believemy's, <text> labels a logo, shows a percentage in the middle of a circular gauge, names the axes of an SVG chart, or makes a word follow a path with <textPath>. Any SVG icon paired with a word, in a badge system or a dashboard, goes through this element.
Frequently asked questions
x and y?Not directly with y alone, which only handles the baseline. For precise vertical centring, add the dominant-baseline="middle" property, which re-centres the text's box on the given point instead of on its usual baseline.
Yes, unlike text drawn inside an image or a canvas, the content of a <text> element stays real text: it can be selected with the mouse, copied, and indexed by search engines like any other text on the page.
Not natively in most common browsers. The usual approach is to split the text by hand into several <tspan> elements with increasing y coordinates, one line per tspan, or to switch to <foreignObject> to use the regular HTML flow instead.