The <text> element
SVG text is positioned with absolute coordinates, not reflowed like HTML. The x and y attributes place the baseline of the first character — not the top-left corner of the bounding box. This is the most common point of confusion when switching from HTML layout to SVG.
Two attributes control how the text aligns relative to the anchor point you provide: text-anchor handles the horizontal axis and dominant-baseline handles the vertical axis.
text-anchor: horizontal alignment
text-anchor accepts three values:
start— the givenxis the left edge of the text (the default for left-to-right scripts).middle— the givenxis the horizontal center of the text.end— the givenxis the right edge of the text.
The demo below draws three labels all anchored to the same vertical line (x = 100). Notice how the text appears to the right, centered on, or to the left of that line depending on the text-anchor value. This matters any time you want to center a label over a data point or right-align a y-axis label in a chart.
dominant-baseline: vertical alignment
By default, y places the alphabetic baseline — the line that most lowercase letters sit on. If you want to center text vertically in a shape (say, a label inside a circle), use dominant-baseline="middle" combined with text-anchor="middle". The value auto (default), middle, hanging (top of cap height), and central are the most useful.
Styling text
SVG text can be styled using either presentation attributes (directly on the element) or CSS. Both approaches produce the same result, but CSS wins when there is a conflict — it has higher specificity than presentation attributes. In practice, you will see both in the wild; using CSS classes keeps your SVG cleaner and easier to theme.
The key text presentation attributes are: font-family, font-size, font-weight, font-style, fill (text color), stroke (outline), and letter-spacing.
Attributes vs CSS
Notice that the outlined text uses fill="none" with a stroke — a technique with no HTML equivalent. Because SVG text is vector, its outlines are actual geometric paths, making it stroke-able just like any other shape.
Multi-line text with <tspan>
Unlike HTML, SVG <text> does not wrap automatically. If the text is wider than the SVG viewport, it simply overflows — there is no block formatting context. To create multi-line text you use <tspan> child elements, each on its own line.
The typical pattern is to set an absolute x on each <tspan> (to reset the left margin) and a relative dy (to advance down by one line height). Think of dy as "move down n units from the last baseline" — it is a delta, not an absolute y coordinate.
x reset + dy advance
The first <tspan> has dy="0" — it sits exactly on the parent's y="30" baseline. Each subsequent span uses dy="22" to step down 22 user units (roughly 1.4× the 15px font size, a comfortable line height). Individual spans can override inherited attributes — here the third line overrides fill to highlight the key takeaway.
Text on a path
SVG can flow text along any arbitrary <path> using the <textPath> element. The technique requires two steps: first, define a path inside <defs> (so it is reusable but not rendered on its own), then reference it from a <textPath href="#id"> inside a <text> element.
Each character's baseline is placed tangent to the path at its corresponding position. The startOffset attribute moves the text along the path — "50%" combined with text-anchor="middle" centers the text on the curve, which is the most common use case.
Curved text with <textPath>
Text on a circular path
A full-circle <path> (two arc commands) lets you wrap text around a circle — a common technique for badges and labels.
The path defined in <defs> is not rendered — it only provides the geometry for the text to follow. The visible circle is a separate <circle> element drawn on top. This separation of "guide path" and "visible shape" is a common SVG authoring pattern: define the math in <defs>, display separately.