SVG Dateien – Vektorgrafiken für das Web

SVG, die Abkürzung für skalierbare Vektorgrafik (scalable vector graphics), basiert auf XML und kann im Bereich des Webdesigns ein interessantes Grafikformat sein.

Einfache SVG-Grafik
Einfache Grafik mit Text in SVG

Anders als beispielsweise PNG und JPEG enthält eine SVG-Datei nicht die Informationen, welche Pixel, welche Farbe erhalten sollen, sondern was gezeichnet werden soll (z.B. ein rotes Rechteck). Diese Informationen werden im XML-Format gespeichert. SVG-Dateien lassen sich daher mit einem Texteditor ohne weiteres bearbeiten.

Daneben gibt es aber auch klassische Programme und Tools zur SVG-Bearbeitung, wie etwa SVG Online Editoren oder die Open-Source-Software Inkscape.

Eine prominente Nutzerin von SVG-Grafiken ist übrigens die Wikipedia.

Vor- und Nachteile

SVG bietet mehrere Vorteile:

  • Skalierbares Grafikformat: Je näher man an ein auf Pixel basierendes Bild heranzoomt, desto unschärfer wird es. Nicht so bei einem skalierbaren Grafikformat wie SVG. Eine solche Datei lässt sich grundsätzlich beliebig vergrößern und die Elemente werden ebenfalls entsprechend groß generiert.
  • Menschenlesbarer Code/XML: Wer versucht, eine PNG-Datei mit einem Texteditor zu ändern, wird schnell merken, dass das nicht funktioniert. XML hingegen ist vom Menschen ohne Weiteres lesbar. Das eröffnet neben klassischen Bildbearbeitungsprogrammen jede Menge andere Möglichkeiten zur Bearbeitung.
  • Leichte Einarbeitung bei HTML-Kenntnissen: Wer bereits mit HTML vertraut ist, der wird sich auch sehr schnell in SVG einarbeiten können. HTML weist schließlich gewisse Gemeinsamkeiten mit XML auf – zumindest optisch.
  • Bereits zahlreiche Funktionen: SVG kennt Linien, Text-Elemente, Pfade, Ellipsen, Filter, Animationen und vieles mehr.
  • Inline oder als eigene Datei: Du kannst eine SVG-Grafik als eigene Datei abspeichern oder den Code direkt in ein HTML-Dokument einbetten (inline). So können dynamische Grafiken einfach generiert werden.
  • Einfache Übertragung in PNG: Mit Bildbearbeitungsprogrammen wie GIMP oder dem JavaScript SVG Parser canvg wird aus einer SVG-Datei schnell eine PNG-Datei.

Aufgrund seiner Besonderheiten eignet sich das Format nicht für jede Anwendung:

  • Sicherheitsrisiko wegen Code Injections: SVG-Dateien können auch ausführbare Skripte beinhalten und zudem ihrerseits andere (externe) Bilder einbetten, also Inhalte nachladen. Wer Nutzern also beim Upload einer SVG-Datei blind vertraut, schafft Sicherheitslücken.
  • Nicht geeignet für Fotos: Klassische Fotos können zwar in SVG eingebunden werden, lassen sich aber nicht skalieren oder mit SVG „nachzeichnen“. Das Format eignet sich aufgrund seiner Eigenschaften nur für klassische Grafiken.
  • Dateigröße bei individuellen Schriftarten: Wer statt Standard-Schriftarten sich für eine andere Schriftart entschieden hat, muss diese einbinden. Das kann entweder über eine URL erfolgen (Nachteil: Internetverbindung zum Betrachten erforderlich, Daten werden an Server gesendet) oder inline über base64 (Nachteil: Datei wird deutlich größer).

Beispiel einer SVG-Grafik

Eine SVG-Grafik kann zum Beispiel wie folgt aussehen:

<svg version="1.1" baseProfile="full" width="600" height="600" xmlns="http://www.w3.org/2000/svg">
	<rect id="svg_background" width="100%" height="100%" x="0" y="0" style="fill:#fff;" ></rect>
	<rect x="150" y="150" width="300" height="300" style="fill: rgb(104, 104, 104); stroke: rgb(45, 45, 45); stroke-width: 1;"></rect>
	<text x="193" y="327" style="font-size: 55px; font-family: Arial; fill: rgb(255, 255, 255); ">SVG Bild</text>
</svg>

Das svg-Element benötigen wir sowohl, wenn wir SVG in einer .svg-Datei speichern als auch, wenn wir es inline einbetten. Die width und height-Angaben sind der Ausgangspunkt für die späteren Koordinatenangaben. Natürlich kann das SVG-Bild dennoch beliebig (z.B. auf 6000×6000 Pixel) skaliert werden.

Sodann folgen unterschiedliche Elemente, die unsere Grafik beinhalten soll.

Mit dem ersten rect zeichnen wir ein Rechteck, das die gesamte Fläche ausfüllt. Über das style-Attribut können wir mit der Eigenschaft fill (statt wie in HTML/CSS mit background/background-color) die (Hintergrund-)Farbe festlegen. Die Elemente werden nämlich auch in der Reihenfolge gezeichnet, in der sie angegeben werden. In diesem Fall werden also alle nachfolgenden SVG-Elemente den Hintergrund ggf. teilweise überschreiben.

Das zweite rect platzieren wir in der Mitte (x und y) und zwar mit Rahmen (stroke und stroke-width).

Anschließend schreiben wir den text „SVG Bild“ in der Schriftart Arial.

Weitere SVG-Elemente

Daneben gibt es zahlreiche weitere Elemente, wie beispielsweise circle, line und path. Einen guten Überblick bietet das W3Schools Tutorial.

Bei text-Elementen müssen besondere Schriftarten ggf. eingebunden werden. Dafür empfiehlt es sich z.B. .ttf-Dateien in web-geeignete, komprimierte .woff oder .woff2-Dateien umzuwandeln, wofür sich online entsprechende Tools finden. .woff-Dateien werden von den gängigen Browsern unterstützt, wohingegen die Einbettung von .ttf-Dateien in eine SVG-Datei oft nicht unterstützt wird.

Diese .woff-Datei wird dann als base64-Zeichenkette eingebunden, das sieht dann beispielsweise so aus:

<svg version="1.1" baseProfile="full" width="600" height="600" xmlns="http://www.w3.org/2000/svg">
	<defs>
		<style type="text/css">
			@font-face{font-family:'Neue Schriftart';src:url(data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAA...) format('woff');}
		</style>
	</defs>

Die eingebettete Schriftart kann nun mit dem definierten Namen „Neue Schriftart“ verwendet werden.

Tipps zur SVG-Sicherheit

Wie bereits geschildert, kann SVG – zum Beispiel wenn es von Nutzern hochgeladen wurde – potenziell auch JavaScript und externe Inhalte beinhalten. Wenn eine SVG-Grafik über ein img-Element eingebunden wird, wird JavaScript nicht ausgeführt. Externe Inhalte, etwa Schriftarten, sollten ebenfalls nicht abgefragt werden, wobei insoweit nicht auf alle Browser Verlass ist.

Wenn du dennoch inline SVG einbinden möchtest, solltest du jedes einzelne Element überprüfen. Mit PHP DomDocument und nach dem nachfolgenden Skript von mir (frei verwendbar, Quellenangabe nicht entfernen) kannst du unterstützte Elemente und Attribute festlegen und die übrigen entfernen:

// Quelle: https://www-coding.de/svg-vektorgrafiken-fuer-das-web/ ‎//

// Unterstützte Elemente, ggf. erweitern //
$supportedTags = array('svg'=>1, 'title'=>1, 'text'=>1, 'rect'=>1, 'circle'=>1, 'ellipse'=>1, 'line'=>1, 'polygon'=>1, 'polyline'=>1);

// Unterstützte Attribute, ggf. erweitern //
$supportedAttributes = array('id'=>1, 'width'=>1, 'height'=>1, 'x'=>1, 'y'=>1, 'x1'=>1, 'x2'=>1, 'y1'=>1, 'y2'=>1, 'cx'=>1, 'cy'=>1, 'fx'=>1, 'fy'=>1, 'points'=>1, 'd'=>1, 'r'=>1, 'rx'=>1, 'ry'=>1, 'stroke'=>1, 'stroke-width'=>1, 'fill'=>1, 'in'=>1, 'in2'=>1, 'stdDeviation'=>1, 'result'=>1, 'mode'=>1, 'filter'=>1, 'offset'=>1, 'style'=>1, 'font-size'=>1, 'font-family'=>1, 'transform'=>1);

$xml = new DOMDocument();
$loadSuccess = @$xml -> loadXML($svgContent);
					
if ($loadSuccess === false) {
	// Fehler, wenn ungültiges XML //
	$error = true;
} else {
	$allElements = $xml -> getElementsByTagName('*'); // generiert dynamische Liste
	$cacheDelElements = array(); // Vorgemerkte zu löschende Elemente

	foreach ($allElements AS $element) {
		if (!isset($supportedTags[$element -> tagName])) {
			// Nicht unterstützte Elemente für Löschen vormerken (da dynamische Liste) //
			$cacheDelElements[] = $element;
			continue;
		}

		$cacheDelAttributes = array(); // Vorgemerkte zu löschende Attribute		
		$attrLength = $element -> attributes -> length;
		for ($i = 0; $i < $attrLength; $i++) {
			if (!isset($supportedAttributes[$element -> attributes -> item($i) -> name])) {
				// Nicht unterstützte Attribute für Löschung vormerken (da dynamische Liste) //
				$cacheDelAttributes[] = $element -> attributes -> item($i);
				continue;
			}
		}
							
		// Vorgemerkte Attribute löschen //
		foreach ($cacheDelAttributes AS $attribute) {
			$element -> removeAttributeNode($attribute);
		}
	}

	// Vorgemerkte Elemente löschen //
	foreach ($cacheDelElements AS $element) {
		$element -> parentNode -> removeChild($element);
	}
}

Dabei ist insbesondere zu beachten, dass DOMDocument dynamische Listen generiert und es daher zu unerwarteten Ergebnissen führen würde, würde man die Elemente nicht erst vormerken, sondern direkt löschen.

Ausblick zur SVG-Entwicklung

Seit mehr als 15 Jahren wird über ein SVG2 nachgedacht. Eine aktuelle W3C-Diskussionsgrundlage stammt aus dem Oktober 2018. Eine Standard für SVG2 wurde damit hingegen noch nicht kreiert. Es bleibt daher abzuwarten, wann SVG2 so weit sein wird und mit welchen neuen Features.

Bis dahin bleibt aber das „alte“ SVG als skalierbare Vektorgrafik mit vielen Funktionen ein interessante Option, um Grafiken auf der eigenen Website einzubinden und zu erstellen.