SVG Typography & Vector Design

How to Use SVG Text, tspan & textPath: Curved Text & Typography Guide (2026)

SVG Typography Curved Text Along Bézier Curves and Baseline Alignment Systems
Figure 1: Architectural diagram showing glyph baseline projection along sinusoidal wave curves and circular arcs with dominant-baseline alignment vectors.

1. Anatomical Foundations: The <text> Element & Coordinate Anchors

The fundamental container for all vector typography is the <text> element. Unlike HTML block elements (such as <p> or <div>), an SVG text element does not have margins, padding, or an intrinsic width that causes words to automatically wrap to the next line.

Instead, an SVG text element establishes a cursor coordinate origin defined by its x and y attributes:

<svg viewBox="0 0 400 120" xmlns="http://www.w3.org/2000/svg">
  <text x="40" y="70" font-family="'Inter', sans-serif" font-size="28" fill="#F2F2F2">
    Production Vector Typography
  </text>
</svg>

The most common stumbling block for web developers transitioning from CSS to SVG is the meaning of the y coordinate. In HTML, placing an element at top: 70px positions its top border at 70px. In SVG, however, the y attribute defaults to the alphabetic baseline upon which Roman letters (such as 'A', 'H', 'x') sit. Any descending characters (such as 'g', 'j', 'p', 'q', 'y') extend below this y coordinate.

SVG Text Coordinate Anchor Rule
Cursor Position = (x, y) → Default Anchor: Bottom-Left Alphabetic Baseline
Without baseline adjustments, text placed at y="0" renders entirely above the top edge of the viewBox, effectively disappearing outside the visible canvas. Always offset y by at least the font size.

2. Multi-Line Spanning & Relative Offsets: Mastering <tspan>

Because native SVG does not support automated word wrapping (until the experimental SVG 2 inline-size property achieves universal adoption), creating multi-line text blocks requires the <tspan> element.

A <tspan> functions like an HTML <span>, but with coordinate-shifting capabilities via four positioning attributes:

  • x & y (Absolute Coordinates): Hard-resets the rendering cursor to a new absolute position in the viewBox. Setting x="40" on a child <tspan> returns the cursor to the left margin.
  • dx & dy (Relative Delta Offsets): Shifts the cursor relative to the end position of the preceding glyph. For example, dy="1.2em" moves down by exactly one line height increment.

The Clean Multi-Line Paragraph Pattern

To author a clean, responsive multi-line paragraph without hardcoding pixel heights, combine absolute x with relative dy:

<text x="30" y="50" font-family="'Inter', sans-serif" font-size="16" fill="#D4D4D4">
  <tspan x="30" dy="0">First line of descriptive metadata text.</tspan>
  <tspan x="30" dy="1.4em">Second line automatically indented with proportional spacing.</tspan>
  <tspan x="30" dy="1.4em" font-weight="700" fill="#C1DD2D">Third line highlighted with custom brand token color.</tspan>
</text>

Using dy="1.4em" ensures that if you adjust the parent font-size in CSS, the line spacing scales proportionally without overlapping lines.

3. The Baseline Problem: dominant-baseline vs. alignment-baseline

Vertical alignment in SVG has confused developers for decades because SVG defines over a dozen different baselines derived from global font tables. The two primary attributes governing vertical alignment are:

  1. dominant-baseline: Applied to the parent <text> (or inherited by children), this property establishes which baseline table from the font metrics is used as the active reference.
  2. alignment-baseline: Applied to child elements (like <tspan> or <textPath>), specifying how the child aligns relative to its parent's dominant baseline.
dominant-baseline Value Visual Reference Line Vertical Anchor Behavior Recommended Production Usage
alphabetic (Default) Bottom edge of flat Latin letters (e.g. 'x', 'm') Descenders ('g', 'p') hang below the Y coordinate Standard body text, traditional editorial layouts
central (Recommended) Mathematical center of the capital letters Centers glyphs vertically right on the Y coordinate Centering text inside badges, circular buttons, and UI icons
middle Geometric middle of the em-square box Near central, but based on full font em-box metrics Mathematical notations and legacy SVG 1.1 chart alignment
hanging Top edge of capital glyphs (Tibetan/Indic script) Glyphs hang completely downward from the Y coordinate Text positioned flush against the top border of a container
text-bottom / text-top Extremes of the font bounding box including accents Aligns to extreme font ascender/descender bounds Inline super-scripts, sub-scripts, and footnote markers
The Gold-Standard Universal SVG Centering Formula
<text x="50%" y="50%" text-anchor="middle" dominant-baseline="central">Centered Label</text>
Pairing text-anchor="middle" (horizontal center) with dominant-baseline="central" (vertical center) places the exact visual center of any word onto the target coordinate across all screen resolutions.

4. Fixing the Infamous Safari/WebKit Baseline Alignment Bugs

Developers who test exclusively in Chrome or Firefox are often shocked to discover that their centered SVG text appears noticeably shifted downward or upward in Apple Safari (iOS and macOS). This discrepancy stems from two long-standing WebKit rendering behaviors:

  • Inheritance Drop on Nested Spans: In WebKit, a dominant-baseline assigned to the outer <text> container frequently fails to cascade down into child <tspan> elements if those spans have independent styling or transforms applied.
  • Font Metric Discrepancies: WebKit and Blink calculate the capital em-height differently when rendering system fonts like system-ui or -apple-system versus web fonts like Inter or Roboto.

The Bulletproof WebKit Cross-Browser Patch

To eliminate baseline drift in Safari, always declare both dominant-baseline and alignment-baseline explicitly on both the parent <text> and any child <tspan> or <textPath> tags:

<!-- Cross-Browser Bulletproof Centered Text -->
<text x="100" y="50"
      text-anchor="middle"
      dominant-baseline="central"
      alignment-baseline="central"
      style="dominant-baseline: central; alignment-baseline: central;">
  <tspan dominant-baseline="central" alignment-baseline="central">Rock Solid in Safari</tspan>
</text>

5. Flowing Text Along Arbitrary Geometry: The <textPath> Architecture

The true superpower of SVG typography is the <textPath> element. Unlike HTML and CSS, which require complex canvas hacks or splitting text into dozens of rotated spans with JavaScript, SVG natively bends and warps text along any mathematical vector curve.

The Core Mechanism

  1. Define the Guide Path in <defs>: Author a vector path inside the SVG’s <defs> section (or directly in the canvas) and give it a unique id. The path can be a Bézier curve, an arc, a circle, or a complex wave.
  2. Wrap Text in <textPath>: Inside your <text> element, wrap the content in a <textPath> tag and link it to the path's ID via the href attribute (e.g., href="#guideCurve").
  3. Browser Tangent Mapping: The browser computes the arc-length parameterization of the path and calculates the tangent vector at each character's position, rotating and translating each glyph individually along the curve.
<svg viewBox="0 0 500 200" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <!-- S-Curve Path Definition -->
    <path id="waveCurve" d="M 40 140 C 160 40, 340 240, 460 140" fill="none" />
  </defs>

  <!-- Visible Guide Line (Optional) -->
  <path d="M 40 140 C 160 40, 340 240, 460 140" fill="none" stroke="#333" stroke-dasharray="4 4" />

  <text font-family="'Inter', sans-serif" font-size="20" font-weight="700" fill="#C1DD2D">
    <textPath href="#waveCurve" startOffset="50%" text-anchor="middle">
      Dynamic Curving Vector Typography Along Path
    </textPath>
  </text>
</svg>

6. Path Offsets, Alignment & Curve Directionality

When positioning text along a curve, three key attributes govern its layout:

  • startOffset: Controls the distance along the path where the text begins. It accepts either an absolute length (e.g., startOffset="80px") or a percentage of the total path length (e.g., startOffset="50%").
  • text-anchor: Works in tandem with startOffset. If you set startOffset="50%" and text-anchor="middle", the text is centered along the curve. If text-anchor="start", the beginning of the text starts at 50%. If text-anchor="end", the end of the text stops at 50%.
  • side (SVG 2): Dictates which side of the path the glyphs sit on (left or right). The default is left (relative to the path's drawing direction).
The Path Direction Law (Why Text Appears Upside Down)
Glyph Orientation = Tangent Vector along d="M ... A ..." direction
A path drawn clockwise places glyphs facing outward from the curve. A path drawn counter-clockwise flips glyphs upside-down inside the curve. If text is inverted, reverse the starting and ending coordinates in your path definition.

7. Interactive Developer Studio: Live Curved Text & Baseline Studio

Experiment with the live studio below to test typography along different vector curves, adjust start offsets, toggle baseline alignments, and generate copy-paste SVG code.

Curved Text & Baseline Visual Studio
Interactive Tool
ICONSTASH • VECTOR TYPOGRAPHY STUDIO • 2026 •
Computed Path Length
942 px
Active Baseline
central
Anchor Offset
50% (middle)
// Generated SVG Typography Code

8. Web Fonts, FOUT/FOIT Prevention & System Stacks in SVG

When using custom web fonts (like Inter, Plus Jakarta Sans, or JetBrains Mono) inside an SVG, browsers must download the corresponding WOFF2 file before glyphs can be rasterized. If not handled correctly, this triggers Flash of Unstyled Text (FOUT) or invisible text (FOIT) that disrupts layout.

Method 1: Embedding Base64 WOFF2 Fonts Directly in <style>

For standalone SVGs (such as downloaded icons, social share cards, or SVG files loaded via <img> tags), external HTTP font links are blocked by browser security sandbox policies. The only way to guarantee custom typography is inlining a subsetted WOFF2 font as Base64:

<svg viewBox="0 0 400 100" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <style>
      @font-face {
        font-family: 'InterSubset';
        src: url('data:font/woff2;base64,d09GMgABAAAAAA...') format('woff2');
        font-weight: 700;
        font-style: normal;
      }
      .brand-title {
        font-family: 'InterSubset', system-ui, sans-serif;
        font-size: 24px;
        fill: #C1DD2D;
      }
    </style>
  </defs>
  <text x="20" y="55" class="brand-title">IconStash Pro Typography</text>
</svg>

Method 2: Zero-Overhead System Font Stacks

If you wish to avoid bundle bloat and ensure zero network delay, use high-performance native system font stacks:

font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

System fonts render instantly with zero layout shifts (CLS), sub-pixel rendering crispness on high-DPI displays, and native platform familiar aesthetics.

9. Text Accessibility: Screen Readers, Search Indexing & WCAG

A major advantage of SVG text over raster graphics is that it remains authentic text within the browser's Accessibility Object Model (AOM). Screen readers like VoiceOver, NVDA, and JAWS can parse and vocalize SVG text directly.

To ensure 100% WCAG 2.2 AA compliance when deploying SVG typography:

  1. Assign Semantic Role: Add role="img" and an aria-label to the parent SVG container if the text forms a visual graphic or logo banner.
  2. Include <title> and <desc>: Place descriptive <title> and <desc> elements as the first direct children of the <svg> element.
  3. Decorative Aria-Hidden: If the text along a path is purely decorative (for example, a repeating circular watermark behind a main heading), mark it with aria-hidden="true" so screen readers do not repeat redundant phrasing.
  4. Contrast Compliance: Ensure text fill colors exceed a 4.5:1 contrast ratio against the background (e.g., our light mode accent uses WCAG-compliant #4D6300 with 5.2:1 contrast against light cards).

10. Frequently Asked Questions

How do you vertically center text in SVG?

The most reliable cross-browser method to vertically center SVG text at a specific coordinate is setting dominant-baseline="central" alongside text-anchor="middle". dominant-baseline="central" aligns the mathematical vertical midpoint of uppercase glyphs directly onto the target Y-coordinate, avoiding the lower descender drift caused by the default alphabetic baseline.

Why does dominant-baseline fail or misalign in Safari (WebKit)?

Safari and WebKit have historical bugs where dominant-baseline inherited from a parent <text> element fails to apply down into nested <tspan> elements or dynamic text updates. To fix this, explicitly assign dominant-baseline directly to the <tspan> tag itself, or set alignment-baseline="central" as an explicit inline fallback attribute.

How does textPath curve text along an SVG path?

The <textPath> element references a geometry <path> via its href (or legacy xlink:href) attribute. The browser computes the arc-length of the referenced path and maps each glyph's baseline tangent to the curve. You control placement using startOffset (e.g. startOffset="50%" combined with text-anchor="middle" centers the text perfectly along the curve).

What is the difference between absolute x/y and relative dx/dy in <tspan>?

In <tspan>, x and y set new absolute coordinates within the SVG viewBox, resetting the cursor location. In contrast, dx and dy apply relative offsets from the end position of the preceding glyph. For example, dy="1.2em" creates a clean line break without needing to hardcode absolute pixel positions.

How do you make text along a textPath appear on the outside of a circle instead of upside down?

Glyphs on a <textPath> align along the direction that the underlying <path> was drawn. If text on a circular arc appears upside down, the path was drawn counter-clockwise instead of clockwise. You can either reverse the path coordinates (switching the sweep-flag in arc commands) or use the SVG 2 side="right" attribute.

Is text inside an SVG readable and accessible to search engines and screen readers?

Yes, native SVG <text>, <tspan>, and <textPath> elements are fully selectable by users, indexable by Google and Bing search crawlers, and read by accessibility screen readers. To maximize accessibility, assign role="img" and an aria-label or nested <title> to the parent SVG container.