Signatur
Beschreibung
SVGTSpanElement ist die DOM-Schnittstelle für das SVG-Element <tspan>. Ein <tspan> steht immer innerhalb eines <text>- oder eines anderen <tspan>-Elements. Man kann damit einzelne Wörter oder Zeilen anders einfärben, verschieben oder auszeichnen, ohne den Textfluss aufzuteilen.
Die Schnittstelle bringt selbst keine eigenen Eigenschaften oder Methoden mit. Alles wird geerbt: von SVGTextPositioningElement die animierbaren Positionsattribute x, y, dx, dy und rotate (jeweils als SVGAnimatedLengthList bzw. SVGAnimatedNumberList), von SVGTextContentElement Mess- und Abfragemethoden wie getComputedTextLength(), getNumberOfChars(), getSubStringLength() und getStartPositionOfChar() sowie von SVGGraphicsElement Methoden wie getBBox().
Häufige Einsatzfälle sind mehrzeiliger Text (SVG bricht Zeilen nicht automatisch um, deshalb setzt man pro Zeile einen <tspan> mit x und dy), Hervorhebungen innerhalb eines Satzes und Hoch- oder Tiefstellungen über dy oder baseline-shift.
Wenn du <tspan>-Elemente per Skript erzeugst, musst du document.createElementNS() mit dem SVG-Namensraum http://www.w3.org/2000/svg verwenden. Mit document.createElement("tspan") entsteht nur ein unbekanntes HTML-Element, das nichts darstellt.
Rückgabewert
document.createElementNS("http://www.w3.org/2000/svg", "tspan") oder durch Abfrage eines vorhandenen <tspan>-Elements im DOM.Beispiele
tspan erzeugen und in einen Text einfügen
const SVG_NS = "http://www.w3.org/2000/svg";
const svg = document.createElementNS(SVG_NS, "svg");
svg.setAttribute("width", "300");
svg.setAttribute("height", "60");
const text = document.createElementNS(SVG_NS, "text");
text.setAttribute("x", "10");
text.setAttribute("y", "30");
text.append("Status: ");
const span = document.createElementNS(SVG_NS, "tspan");
span.setAttribute("fill", "crimson");
span.setAttribute("font-weight", "bold");
span.textContent = "Fehler";
text.append(span);
svg.append(text);
document.body.append(svg);
console.log(span instanceof SVGTSpanElement);
console.log(span instanceof SVGTextPositioningElement);
Mehrzeiligen Text mit x und dy setzen
const SVG_NS = "http://www.w3.org/2000/svg";
const text = document.querySelector("svg text");
const lines = ["Erste Zeile", "Zweite Zeile", "Dritte Zeile"];
text.textContent = "";
lines.forEach((line, i) => {
const tspan = document.createElementNS(SVG_NS, "tspan");
tspan.setAttribute("x", text.getAttribute("x") ?? "0");
// Erste Zeile bleibt auf der Grundlinie, weitere rücken um 1.2em nach unten
tspan.setAttribute("dy", i === 0 ? "0" : "1.2em");
tspan.textContent = line;
text.append(tspan);
});
console.log(text.querySelectorAll("tspan").length);
Geerbte Positions- und Messwerte auslesen
// HTML: <svg><text x="10" y="40">Preis: <tspan id="preis" dx="5">49 €</tspan></text></svg>
const tspan = document.getElementById("preis");
// dx ist eine SVGAnimatedLengthList
const dx = tspan.dx.baseVal;
console.log(dx.numberOfItems, dx.getItem(0).value);
console.log(tspan.getNumberOfChars());
console.log(tspan.getComputedTextLength() > 0);
Wörter im Text dynamisch hervorheben
const SVG_NS = "http://www.w3.org/2000/svg";
const highlight = (textEl, word) => {
const parts = textEl.textContent.split(word);
textEl.textContent = "";
parts.forEach((part, i) => {
textEl.append(part);
if (i < parts.length - 1) {
const mark = document.createElementNS(SVG_NS, "tspan");
mark.setAttribute("fill", "orange");
mark.textContent = word; // textContent statt innerHTML: kein XSS
textEl.append(mark);
}
});
};
const label = document.querySelector("svg text");
highlight(label, "SVG");
console.log(label.querySelectorAll("tspan").length);
// Wichtig · Fallstricke
- Namensraum:
document.createElement("tspan")liefert einHTMLUnknownElement. Verwende immercreateElementNS("http://www.w3.org/2000/svg", "tspan"). - Nur innerhalb von Text: Ein
<tspan>direkt unter<svg>oder<g>wird nicht dargestellt. Es muss in<text>,<textPath>oder einem anderen<tspan>stehen. - Kein automatischer Umbruch: SVG 1.1 bricht Zeilen nicht um. Für mehrere Zeilen brauchst du einen
<tspan>pro Zeile mitxunddy. - Listenwerte:
x,y,dx,dyundrotatesind animierte Listen. Gelesen und geschrieben wird über.baseVal, nicht direkt als Zahl. Für einfache Fälle istsetAttribute()meist bequemer. - Messungen:
getComputedTextLength()undgetBBox()geben erst dann sinnvolle Werte zurück, wenn das Element im Dokument hängt, dargestellt wird und die Schrift geladen ist (siehedocument.fonts.ready). Beidisplay: noneerhältst du 0. - Sicherheit: Setze Nutzereingaben mit
textContentund nicht mitinnerHTML, damit kein Markup eingeschleust werden kann. - Kompatibilität: Wird in allen modernen Browsern unterstützt. Die Vererbung von
SVGTextPositioningElementist einheitlich umgesetzt. Das SVG-2-AttributtextLengthauf<tspan>wird teilweise unterschiedlich dargestellt.