SVG text und tspan: Schrift, Farbe, an Pfad ausrichten und rotieren

Das SVG-text-Element zeigt Texte in der Grafik und ist Klartext – kann also auch von Suchmaschinen indexiert und von Readern vorgelesen werden. SVG text wird durch Attribute und CSS ähnlich dargestellt wie Text in HTML: Schrift, Schriftgröße und -farbe, Text rotieren und an Text an Pfad ausrichten.

SVG text als Klartext: durchsuchbar, indexierbar

font-family – Schrift in SVG laden

1️⃣ Text mit einer individuellen Schrift funktioniert in SVG genauso wie in HTML: Die Schrift kann im style-Element der SVG-Grafik eingebunden und geladen werden. Dafür muss die Schrift allerdings genauso wie in HTML-Seiten auf dem System des Benutzers vorhanden sein. font-family wird darum am besten mit einem Fallback angegeben.

Schrift laden

1️⃣ Schrift im Style-Element laden

<svg viewBox="0 0 528 111" xmlns="http://www.w3.org/2000/svg">
	<style>
		text {
			font-family:Lobster, Arial, Helvetica, sans-serif;
			font-size:116px;
			fill: oklch(0.75 0.05 190);
		}
	</style>
	<rect width="528" height="111" />
	<text x="13" y="105">Hallo Welt</text>
</svg>

2️⃣ Ladbare Schriften werden mit @font-face geladen. Da SVG in einem img-Tag keine externen Ressourcen lädt, muss die Grafik inline oder in einem iframe eingesetzt werden.

Hallo Welt

2️⃣ Schrift als Webfont mit @font-face laden

<svg version="1.1" viewBox="0 0 528 111" xmlns="http://www.w3.org/2000/svg">
<style>
	@font-face {
		font-family: "lobster";
		src: url("lobster-v20.woff2") format("woff2");
	}

	text {
		font-family: "lobster";
		font-size:116px;
		fill: oklch(0.75 0.05 190);
	}
</style>
<rect width="528" height="111" style="fill:oklch(0.96 0.03 100)"/>
<text x="13" y="105">Hallo Welt</text>
</svg>

3️⃣ Damit die Grafik in einem img-Tag geladen werden kann, wandelt die sicherste Variante die Schrift in Pfade um. Dabei wird die SVG-Datei deutlich größer und der Text kann nicht einfach geändert werden.

Schrift laden

3️⃣ Schrift in SVG-Pfad umgewandelt

<svg version="1.1" viewBox="0 0 528 111" xmlns="http://www.w3.org/2000/svg">
	<rect width="528" height="111" style="fill:oklch(0.96 0.03 100)"/>
	<g style="fill: oklch(0.75 0.05 190)">
		<path d="m42 26q-7.8 3.3-12 9.8-4.2-… z"/>
		<path d="m104 106q-6.6 0-11-4.5-4.4-… z"/>
			…
	</g>
</svg>

Text positionieren

SVG rendert Text genauso wie Formen: Das SVG text-Element enthält die Informationen zur Position des Texts, Transformationen sowie Eigenschaften, die als CSS style oder SVG-Attribut festgelegt werden.

<text x="50" y="100">Hallo    SVG</text>

Die Bestimmung der Position richtet sich nach dem ersten Buchstaben unten links (bei Schriftrichtung links nach rechts) und wird mit x und y Koordinaten beschrieben (Schrift von oben nach unten: style="writing-mode: tb;").

SVG Text positionieren
SVG-Text positionieren

Ohne font-size und font-family- und fill-Attribut rendern die Browser Schriftart, Schriftgröße und -farbe entsprechend ihren Voreinstellungen – genauso wie bei HTML. Inline-SVG erbt die Schrift von seinem umfassenden Element, in externen SVG-Bildern ohne Deklaration der Schrift nutzen die Browser meist eine Serifenschrift.

Genauso wie in HTML unterdrückt SVG aufeinander folgende Leerzeichen und Zeilenumbrüche im Text.

font-size

Üblich ist die Angabe von font-size ohne Einheit, der Default-Wert ist 16px. em als Einheit setzt ebenfalls 16px an. Grundlage ist das SVG-Koordinatensystem, also viewBox.

rem funktioniert, ist aber in SVG nur unter bestimmten Bedingungen sinnvoll. Der Haken: SVG hat kein eigenes »Root-Element« wie HTML, deshalb bezieht sich rem immer auf das umgebende Dokument.

font-size in Prozent-Angaben: font-size="100%" bringt 16px, font-size="50%" 8px.

M M
<svg viewBox="0 0 100 100" width="100%" height="100%">
	<text x="10" y="90" font-size="100px">M</text>
</svg>

<svg viewBox="0 0 500 500" width="100%" height="100%">
	<text x="10" y="90" font-size="100px">M</text>
</svg>

Zeilenumbruch in SVG-Text

Um es gleich vorweg zu sagen: In SVG gibt keinen automatischen Zeilenumbruch wie in HTML-p-Elementen oder Illustrationsprogrammen. Es gab ein einen komplizierten Ansatz mit flowRoot, flowRegion und flowPara, der in Inkscape immer noch zur Verfügung steht, aber dieser Teil der SVG-Spezifikation ist aus dem Draft-Status nie herausgekommen.

Die Browser unterstützen flowRoot nicht und rendern den Text nicht. Das nicht gerade komfortable tspan-Element ist weiterhin die Lösung für mehrzeilige Texte.

SVG Text mit Zeilenumbruch
SVG Text mit Zeilenumbruch: tspan
<text font-family="sans-serif" font-size="40px" fill="cornflowerblue">
	<tspan x="50" y="50">Hallo SVG</tspan>
	<tspan x="50" y="100">Alles absolut</tspan>
</text>

Am Ende gibt es aber doch einen Ausweg aus dem Dilemma: SVG foreignObject setzt Elemente aus anderen XML-Namensräumen in ein SVG und rendert so Text mit allen Schikanen in die Grafik.

Text in einem foreignObject wird umgebrochen
<svg width="300" height="100" xmlns="http://www.w3.org/2000/svg">
	<foreignObject x="10" y="10" width="280" height="80" style="background: gainsboro">
		<div xmlns="http://www.w3.org/1999/xhtml" style="width: 100%; overflow-wrap: break-word; padding: 4px">
			Text kann mithilfe eines foreignObject innerhalb von SVG umgebrochen werden.
		</div>
	</foreignObject>
</svg>

SVG ist eine XML-Sprache und konsistent zu anderen XMP-Sprachen – also auch zu HTML. Wir können nicht nur SVG direkt in HTML-Seiten einsetzen, sondern HTML in SVG-Dateien.

Das foreignObject-Element nimmt Elemente aus anderen Namensräumen auf.

HTML in SVG
SVG foreignObject

Zeilenabstand mit dy

tspan positioniert Text in Text-Elementen in ein eigenes Koordinatensystem. SVG tspan sorgt für einen Zeilenbruch in mehrzeiligen Texten und bringt CSS wie fill, font-size oder font-weight zu Textfragmenten.

Zeilenabstand dy in tspan-Elementen

CSS line-height wirkt nicht in SVG Text. Die einfachste Variante für einen Zeilenumbruch mit tspan ist ein relativer Zeilenabstand dy anstelle einer absoluten y-Position.

<text y="130" font-size="1em" stroke-width="1">
	<tspan x="160" dy="1.5em" font-weight="400">Ginseng</tspan>
	<tspan x="160" dy="1.5em" font-style="italic">Panax ginseng</tspan>
	<tspan x="160" dy="1.5em" font-size="0.9em" font-weight="300">Asiatischer Ginseng oder </tspan>
	<tspan x="160" dy="1.5em" font-size="0.9em" font-weight="300">Koreanischer Ginseng</tspan>
</text>

Bei einem relativen Abstand muss nur das umfassende text-Element verschoben werden, dann wandern die darunter liegenden tspan-Element automatisch im richtigen Abstand mit. Genauso funktioniert der automatische Abstand zwischen Textzeilen beim Vergrößern bzw. Verkleinern des Text-Elements.

SVG text und CSS style

Wie bei den meisten SVG-Tags kann ein großer Teil der Attribute für das Rendering in ein style-Attribut gesetzt und als CSS gerendert werden. CSS class ist ebenfalls ein gültiges Attribut von SVG-Elementen und damit auch von text.

CSS style für SVG Text

  • font-family
  • font-size
  • fill (anstelle von color in HTML)
  • font-weight
  • font-style
  • @font-face
  • text-decoration
  • text-transform (nur mit CSS Style)
  • letter-spacing
  • word-spacing
  • font-variant

Was geht nicht?

  • line-height
  • fill: linearGradient
  • white-space

Ein relativer Abstand von tspan-Elementen ersetzt line-height, für Verläufe hat SVG mit linearGradient eine eigene Technik.

Hallo SVG
<!-- 
    comment
-->
<text  x="50" y="50">Hallo    SVG</text>

Zuverlässiger als die SVG-Attribute für SVG-Text ist der jeweilige CSS-Stil, nur die wahrhaftigen Basisstile wie font-weight und font-style gehen immer auch als SVG-Attribut.

text-rendering

Während wir in den meisten Fällen zufrieden sind, wenn der Browser die angeforderte Schrift schnell und gut lesbar darstellt, gibt es empfindliche Elemente wie z.B. der Text eines Logos, bei dem es auf jedes Detail ankommt.

Das Text-Attribut text-rendering bestimmt, wo die Priorität der Darstellung liegt: Geschwindigkeit, Lesbarkeit, Präzision.

Kein finsterer Geselle schlicht durch den Wald
auto
Überlässt dem Browser die Entscheidung über die Qualität des Fonts gegenüber der Geschwindigkeit des Renderns des Texts.
geometricPrecision
Der Browser soll der Präzision der Schrift den Vorzug gegenüber Lesbarkeit und schneller Darstellung geben.
optimizeSpeed
Darstellungsgeschwindigkeit ist wichtiger als Lesbarkeit und Präzision.
optimizeLegibility
Lesbarkeit hat höchste Priorität.
Suchen auf mediaevent.de