Kategorien
HTML/CSS

Alles, was du über SVG wissen musst

Mit der Einführung von HTML5 ab 2004 wurde auch die JavaScript-basierte Zeichenmethode Canvas eingeführt. Bereits seit 2001 gibt es das vektorbasierte SVG-Format, welches allerdings erst in den letzten Jahren parallel zu HTML5 ein wirklicher Erfolg wurde. Beide Formate haben ihre Vor- und Nachteile. Aber welches ist wann besser geeignet? Wo liegen die Vor- und Nachteile?

Anzeige

JavaScript gegen XML-Syntax

Der größte Unterschied zwischen HTML5-Canvas und SVG ist die der Auszeichnung beziehungsweise Programmierung. Per HTML5 wird letztlich nur ein einziges Element („<canvas>“) ausgezeichnet. Der komplette Inhalt der Leinwand wird per JavaScript realisiert.

Entsprechende Methoden ermöglichen es, Formen wie Rechtecke, Kreise und auch komplexe Polygone und Bögen zu zeichnen sowie miteinander zu kombinieren. Für das Aussehen – Füllfarbe sowie Konturenstärke und -farbe – wird ebenfalls JavaScript verwendet.

var leinwand = document.getElementById("leinwand");
var zeichnung = leinwand.getContext("2d");
zeichnung.moveTo(0, 0);
zeichnung.lineTo(200, 200);
zeichnung.lineWidth = 2;
zeichnung.strokeStyle = "red";
zeichnung.stroke();

Im Beispiel wird eine Linie von der Position „0, 0“ zur Position „200, 200“ gezeichnet und rot eingefärbt.

Per SVG würde dieselbe Linie über ein entsprechendes SVG-Element ausgezeichnet.

<line x1="0" y1="0" x2="200" y2="200" stroke-width="2" stroke="red" />

Obwohl das Ergebnis in beiden Fällen identisch ist, erkennt man, dass die SVG-Variante deutlich kürzer ausfällt und aufgrund der XML-Syntax für die Meisten vermutlich deutlich intuitiver auszuzeichnen ist.

Anzeige

Ein weiterer Vorteil im SVG-Format besteht darin, dass die Gestaltung auch per CSS erfolgen kann. Hier lassen sich einzelne Formen per ID oder Klasse einheitlich gestalten.

Bei der Auszeichnung liegt das SVG-Format also vorne. Es ist platzsparender und hat eine einfachere Syntax. Wer zudem grundsätzlich alle Inhalte auch ohne JavaScript anbieten möchte, hat mit HTML5-Canvas ohnehin schlechte Karten.

Pixel gegen Vektoren

Ein weiterer großer Unterschied besteht in der Darstellung der Formate. Während HTML5-Canvas ein pixelbasiertes Format (es wird jeweils ein PNG-Bild im Browser erzeugt) ist, ist das SVG-Format vektorbasiert.

Natürlich kannst du auch per HTML5-Canvas entsprechend Grafiken für hochauflösende Displays erstellen. Aber spätestens beim Hereinzoomen werden Canvas-Zeichnungen pixelig, während SVG-Zeichnungen ihre Schärfe beibehalten.

Auch hier hat das SVG-Format die Nase vorn – zumal du auch innerhalb eines SVG-Dokumentes Bitmaps einbinden kannst.

Interaktionen und Effekte

Da das SVG-Format auch CSS unterstützt, stehen einem alle Möglichkeiten von Stylesheets zur Verfügung. Neben der einfachen Gestaltung lassen sich auch interaktive Effekte einbeziehen.

So kannst du zum Beispiel Hover-Effekte auf einzelne SVG-Formen anwenden, um diese beim Herüberfahren mit der Maus hervorzuheben, farblich zu verändern oder zu vergrößern. Auch Animationen dank der „transition“-Eigenschaft sind auf diese Weise möglich.

Da das SVG-Format auch Verlinkungen erlaubt, kannst du Formen mit einem Verweis versehen und somit aus einzelnen Formen Links erstellen.

Darüber hinaus besteht auch die Möglichkeit, SVG-Elemente per JavaScript anzusprechen und zu manipulieren.

document.getElementsByTagName("rect")[0].setAttribute("width", "200");

Im Beispiel wird ein SVG-Rechteck per JavaScript manipuliert.

Geschwindigkeit

Ein letzter großer Unterschied zwischen HTML5-Canvas und SVG besteht in der Geschwindigkeit, was das Rendern und somit die Darstellung der Zeichnungen im Browser betrifft. Hier hat pauschal erst einmal kein Format die Nase vorn.

Gerade bei weniger komplexen Zeichnungen kannst du den Geschwindigkeitsunterschied vernachlässigen. Aber bei komplexen beziehungsweise großen Zeichnungen werden Unterschiede deutlich.

So wird bei zunehmender Anzahl von Objekten – sowohl einfache Formen als auch komplexe Pfade – das SVG-Format langsamer. Es braucht länger um die Zeichnung zu rendern und somit darzustellen. Das Canvas-Format schneidet hier deutlich besser ab. Je mehr Objekte eine Zeichnung hat, desto performanter verhält sich HTML5-Canvas gegenüber SVG.

Anders sieht es aus, wenn man die Größe der Fläche berücksichtigt. Das SVG-Format kommt mit großen Flächen deutlich besser zurecht und rendert Elemente darauf wesentlich schneller als das Canvas-Format.

Wer also großformatige Zeichnungen einsetzen will, die vielleicht sogar seitenfüllend sind, sollte auf das SVG-Format setzen. Wer hingegen besonders komplexe Elemente rendern muss – beispielsweise komplexe Diagramme –, sollte eher das Canvas-Format nutzen.

Pixelmanipulation

Da es sich nur bei HTML5-Canvas um ein pixelbasiertes Format handelt, kommt Pixelmanipulation beim SVG ohnehin selten in Frage. Allerdings gibt es auch beim SVG-Format die Möglichkeit, mit verschiedenen Filtern zum Beispiel die Farbe eines eingebundenen Bitmaps zu manipulieren.

Aber an sich bietet sich vor allem HTML5-Canvas zur Pixelmanipulation an. Denn das pixelbasierte Format macht es recht einfach möglich, jedes einzelne Pixel eines Bilder über eine entsprechende Funktion zu verändern.

Auf diese Weise lassen sich nicht nur statische Manipulationen realisieren, sondern auch animierte Effekte. Selbst die Echtzeitmanipulation von Videos ist mit HTML5-Canvas möglich.

So lässt sich die Farbe in einem Video – zum Beispiel per Greenscreen-Verfahren – dynamisch durch eine andere Farbe oder Hintergrundgrafik ersetzen. Dazu kannst du per JavaScript auf die Frames eines Videos zugreifen und in diesen beispielsweise eine Farbe durch ein anderes Bild ersetzen.

Zwischenfazit

Die genannten Beispiele zeigen, dass sowohl HTML5-Canvas als auch das SVG-Format jeweils ihre Vor- und Nachteile haben. Bei der Kombination verschiedener hier vorgestellter Möglichkeiten muss man sicher auch immer im Einzelfall abwägen, welches Format die bessere Wahl ist.

Aber grundsätzlich lässt sich Folgendes sagen: Wenn es um statische Zeichnungen geht, bei denen es vor allem auf Skalierbarkeit und die Darstellung auf großer Fläche ankommt, ist das SVG-Format die richtige Wahl.

Bei komplexen Darstellungen, die permanent neu berechnet werden müssen – Echtzeitdaten einer Wetterkarte oder ein Video zum Beispiel –, ist HTML5-Canvas performanter und daher vorzuziehen.

2. SVG & CSS: Was geht, was nicht in der Gestaltung per Stylesheet

Da SVG-Grafiken wie auch HTML-Dokumente über eine Auszeichnungssprache erstellt werden, ist die Erstellung und Bearbeitung per Texteditor möglich. Für die Gestaltung von SVG-Grafiken kann man zudem auf Stylesheets zurückgreifen. Was den Einsatz von CSS betrifft, gibt es neben vielen Gemeinsamkeiten zu HTML jedoch auch einige Unterschiede zu beachten.

Zwischen HTML und CSS gibt es eine klare Trennung: HTML ist für Inhalt und Struktur zuständig, CSS für die Gestaltung. Diese Trennung gibt es im SVG-Format so nicht. Daher wird die Gestaltung von Formen und Texten in der Regel nicht per CSS, sondern über Elementattribute geregelt:

<rect x="10" y="10" width="300" height="100" fill="red" stroke="green" stroke-width="2" />

Im Beispiel wird ein Rechteck gezeichnet, welches per „fill“ eine Farbe erhält. Die Rahmenfarbe und -stärke wird über die Attribute „stroke“ und „stroke-width“ vergeben. Alternativ kann das Aussehen des Rechtecks auch per CSS gestaltet werden:

<rect x="10" y="10" width="300" height="100" style="fill: red; stroke: green; stroke-width: 2" />

Dabei setzt man die Attribute einfach als CSS-Eigenschaften ein. Allerdings funktioniert der Gebrauch von SVG-Attributen als entsprechende CSS-Eigenschaft nicht bei allen Attributen. Positions- sowie Breiten- und Höhenangaben lassen sich nicht per CSS auszeichnen. Daher sind „x“ und „y“ sowie „width“ und „height“ im Beispiel weiterhin als Attribut angegeben.

Wie auch in HTML-Dokumenten lassen sich CSS-Eigenschaften über eine Klasse oder ID einem Element zuordnen. So ist es im SVG-Format möglich, das Aussehen mehrerer Elemente über eine Klasse zu definieren.

<style>
  .beispiel {
    fill: red;
    stroke: green;
    stroke-width: 2;
  }
</style>
<rect x="10" y="10" width="300" height="100" class="beispiel" />

Da das SVG-Format nicht zwischen einem Head- und Bodybereich unterscheidet, teilen sich Stylesheets und die eigentlichen Inhalte gemeinsam das SVG-Element, welches vergleichbar ist mit dem HTML-Element.

Pseudoklassen verwenden

Auch der Einsatz von Pseudoeklassen wie beispielsweise „:hover“ ist innerhalb von SVG-Grafiken möglich – sogar in Kombination mit der CSS3-Eigenschaft „transition“.

<style>
  .beispiel {
    fill: red;
    stroke: green;
    stroke-width: 2;
    transition: all 2s ease;
  }
  .beispiel:hover {
    fill: blue;
  }
</style>

Bewegt man sich über Elemente, denen die Klasse „beispiel“ zugewiesen ist, ändert sich die Füllfarbe von rot nach blau. Damit der Effekt sichtbar ist, darf die SVG-Grafik allerdings nicht per IMG-Element in ein HTML-Dokument eingebunden sein, sondern per EMBED- oder IFRAME-Element:

<embed src="beispiel.svg" />

Das IMG-Element stellt zwar die SVG-Grafik dar, ignoriert aber Hovereffekte und Transitions. Neben der CSS3-Eigenschaft „transition“ ist die Verwendung der „transform“-Eigenschaft möglich. Elemente können auf diese Weise beispielsweise gedreht oder skaliert werden.

<style>
  .beispiel:hover {
    fill: blue;
    transform: rotate(20deg);
  }
</style>

Es empfiehlt sich auch hier, die neuen CSS3-Eigenschaften um die jeweiligen Vendor-Präfixe zu ergänzen, um möglichst viele Browser abdecken zu können. Während Chrome und Firefox die Eigenschaften problemlos interpretieren, verweigert sich der Internet Explorer selbst in der aktuellen Version, obwohl er die CSS3-Eigenschaften innerhalb von HTML-Dokumenten durchaus versteht.

Media Queries und SVG

Ebenfalls möglich, ist der Einsatz von Media Queries innerhalb von SVG-Grafiken. So lassen sich SVG-Grafiken für unterschiedliche Auflösungen anpassen:

<style>
  @media only screen and (max-width: 800px) {
    .beispiel {
      display: none;
    }
  }
</style>

Im Beispiel werden alle Elemente mit der Klasse „beispiel“ nicht angezeigt, sobald die dargestellte Breite der SVG-Grafik kleiner als 800 Pixel ist. Wird eine Grafik per IMG-, EMBED- oder IFRAME-Element in ein HTML-Dokument eingebunden, gilt hierbei die Breite des einbindenden Elementes, nicht die des HTML-Dokumentes.

<embed src="beispiel.svg" width="500" />

Im Beispiel würden Elemente mit der Klasse „beispiel“ nicht dargestellt, da die SVG-Grafik eine Breite von 500 Pixeln hat.

Media Queries in SVG-Grafiken bieten sich auch an, um das Aussehen für den Druck zu optimieren.

<style>
  @media only print {
    .beispiel {
      fill: none;
    }
  }
</style>

Im Beispiel wird bei der Druckausgabe auf die Füllfarbe verzichtet. Der Einsatz von Stylesheets in SVG-Grafiken bietet demnach große Vorteile. Ältere Browser und der letzte Internet Explorer machen jedoch nicht immer mit.

3. CSS statt SVG: Formen erstellen, animieren und morphen

Wenn es um komplexe Formen und Animationen geht, ist SVG häufig das Format der Wahl – das ja auch nicht zu Unrecht. Doch dank neuer CSS3-Eigenschaften erstellst du Formen jenseits von Rechteck und Kreis sogar ganz ohne SVG und animierst diese zudem noch.

Komplexe Formen mit „clip-path“

Die CSS3-Eigenschaft „clip-path“ ermöglicht es, Elemente auf (fast) beliebige Formen zu beschneiden. Dazu stehen dir die geometrischen Grundformen „inset()“ für ein Rechteck, „ellipse()“ und „circle()“ für Ellipse und Kreis sowie für mehreckige Formen „polygon()“ zur Verfügung.

Wenn es darum geht, aus einem Bild oder einem HTML-Element nur einen einfachen rechteckigen oder runden Ausschnitt darzustellen, sind „inset()“, „ellipse()“ und „circle()“ gute Möglichkeiten. Interessant ist aber vor allem die „polygon()“-Funktion, mit der beliebige mehreckige Formen erstellt werden können.

div {
  clip-path: polygon(50% 0%, 65.5% 32.9%, 100% 38.2%, 75% 63.8%, 80.9% 100%, 50% 82.9%, 19.1% 100%, 25% 63.8%, 0% 38.2%, 34.5% 32.9%);
  width: 300px;
  height: 300px;
}

Bei der Verwendung von „polygon()“ werden beliebig viele Koordinatenpaare definiert, die per Komma voneinander getrennt sind. Erlaubt sind nicht nur absolute Werte, sondern auch prozentuale Angaben. Das hat den Vorteil, dass du die Breite und Höhe durch die CSS-Eigenschaften „width“ und „height“ definierst.

Bei der im Beispiel definierten Form handelt es sich um einen Stern. Da die Koordinaten relativ definiert sind, ist es ein Leichtes, die Breite und Höhe der Form zu verändern.

Form animieren per „transition“

Dank der „transition“-Eigenschaft oder der „animation“-Eigenschaft in Kombination mit der „@keyframes“-Regel hast du auch die Möglichkeit, zwischen zwei per „clip-path“ definierten Formen einen animierten Übergang zu erzeugen.

svg_clip-path_animation

Dazu definierst du beispielsweise per „:hover“ eine Pseudoklasse und gibst die Zielform des Polygons an. Wichtig hierbei ist, dass die Anzahl der Koordinaten sowohl in der Quell- als auch in der Zielform identisch sind.

div:hover {
  clip-path: polygon(50% 0%, 80.9% 7.2%, 97.5% 33.7%, 100% 64.6%, 79.4% 88.1%, 50% 100%, 20.6% 88.1%, 0% 64.6%, 2.5% 33.7%, 19.1% 7.2%);
}

Sobald ein Koordinatenpaar zu viel oder zu wenig vorhanden ist, funktioniert der animierte Übergang nicht mehr. Stattdessen wechseln die beiden Formen ohne Animation.

Formen in Illustrator anlegen

Gerade bei so komplexen Formen ist es schwierig, die Koordinaten selbst festzulegen. Da ist es einfacher und hilfreicher, die Form einfach in Illustrator oder einem anderen Zeichenprogramm, welches den SVG-Export beherrscht, zu zeichnen. Willst du die Form später als relative Prozentangaben in der „polygon()“-Funktion angeben, sollte die Form eine Breite oder Höhe von 100 Pixel haben.

Anschließend exportierst du die Zeichnung als SVG und extrahierst die Koordinaten. Achte darauf, dass du auch tatsächlich ein Polygon angelegt hast. Die Form darf keine Bézierkurven enthalten. Im SVG-Quelltext sollte ein „<polygon>“-Element angelegt sein.

svg_clip-path_illustrator

Während die CSS-Funktion „polygon()“ die Koordinatenpaare per Komma trennt und die einzelnen Werte der Paare per Leerzeichen, ist es beim SVG-Format genau anders herum. Du musst also Komma und Leerzeichen austauschen und den Werten jeweils ein Prozentzeichen zuweisen.

<polygon points="50,0 65.5,32.9 100,38.2 75,63.8 80.9,100 50,82.9 19.1,100 25,63.8 0,38.2 34.5,32.9 "/>

Das Beispiel zeigt, die wie Koordinaten im SVG-Quelltext dargestellt sind.

Vor- und Nachteile von CSS-Formen per „clip-path“

Sowohl die CSS-Variante per „clip-path“ als auch die SVG-Möglichkeiten zur Erstellung komplexer Formen haben ihre Vor- und Nachteile. Nachdem Chrome angekündigt hat, dass es SVG-Animationen per SMIL nicht mehr untestützt, sind Formenmorphing per SVG nur noch per JavaScript möglich.

Die Kombination aus CSS-Eigenschaft „clip-path“ zusammen mit der „transition“-Eigenschaft ermöglichen solche animierten Formenübergänge ganz ohne JavaScript.

Ein Nachteil von „clip-path“ ist, dass nur Polygone möglich sind, aber keine Pfade einschließlich Bézierkurven. Hier hat SVG die Nase vorn, da das „<path>“-Element auch mit Bögen, Aussparungen und Kombination mehrerer Formen kein Problem hat.

4. So optimierst du SVG-Dateien für deine Website

Man muss die SVG-Syntax nicht zwingend beherrschen, um Grafiken in das Webformat bringen zu können. Anwendungen wie Illustrator haben entsprechende Exportfunktionen. Und gerade für komplexe Grafiken ist es auch gar nicht sinnvoll oder machbar, diese per Hand auszuzeichnen. Aber bei generierten SVG-Dateien ist es nicht verkehrt, den Quelltext einmal zu überprüfen. Denn hier und da sind häufig Optimierungsmöglichkeiten vorhanden.

Einfache Formen verwenden

SVG kennt eine Vielzahl von Elementen zum Zeichnen von Formen. Neben „<rect>“, „<circle>“ und „<polygon>“ gibt es mit dem „<path>“-Element quasi einen Allrounder, der nicht nur Rechtecke, Kreise und Polygone zeichnen kann, sondern auch sehr komplexe Formen. Dennoch sollte man immer anstreben, nach Möglichkeit die einfache Form zu verwenden – bei einem Kreis also stets „<circle>“. Denn bei einfachen Formen braucht das „<path>“-Element aufgrund seiner Syntax mehr Platz.

<circle cx="75" cy="75" r="75" />
<path d="M75,0C33.6,0,0,33.6,0,75c0,41.4,33.6,75,75,75s75-33.6,75-75C150,33.6,116.4,0,75,0z" />

Das Beispiel zeigt zweimal dieselbe Form. Das „<path>“-Element benötigt aber etwa dreimal so viel Quelltext. Illustrator sucht automatisch das sinnvollste Element – in diesem Fall „<circle>“. Sobald man beispielsweise per Pathfinder zwei Formen vereint oder eine Form abzieht (zum Beispiel eine Aussparung innerhalb des Kreises erstellt), kommt nur noch das „<path>“-Element in Frage.

svg-optimieren_pathfinder
Pathfinder in Illustrator

Illustrator erzeugt jedoch nur aus nicht bearbeiteten Kreisen auch ein „<circle>“-Element. Sobald ein Kreis per Pathfinder behandelt wurde, wird dieser als „<path>“ ausgegeben. Das gilt auch, wenn es sich augenscheinlich um einen einfachen Kreis handelt, also gar keine tatsächliche Veränderung per Pathfinder durchgeführt wurde.

Pfade kombinieren

Wenn Formen dasselbe Aussehen besitzen, kann es sinnvoll sein, diese zu einem Pfad zu kombinieren. Wie erwähnt, wird dazu zwingend das „<path>“-Element erzeugt. Aber wenn die einzelnen Formen aufgrund ihrer Komplexität ohnehin per „<path>“ ausgezeichnet sind, spielt das keine Rolle.

Werden Pfade per Pathfinder vereint, wird nur noch ein „<path>“-Element benötigt. Auch das Aussehen muss in diesem Fall nur noch einmal festgelegt werden. Der Nachteil ist natürlich, dass die einzelnen Formen nicht mehr bearbeitbar sind.

Pfade vereinfachen

Illustrator bietet die Möglichkeit, Pfade zu vereinfachen. Hierbei wird die Anzahl der Punkte eines Pfades reduziert. Diese Funktion solltest du indes nur mit Vorsicht verwenden. Denn nicht jeder Punkt, der dabei weggelassen wird, ist tatsächlich verzichtbar. Dennoch kann gerade bei sehr komplexen Formen eine Reduzierung der Pfade zu einer schlankeren SVG-Datei führen.

svg-optimieren_vereinfachen
Pfade vereinfachen für weniger Punkte

Je nach Form kann ein Pfad schon einmal auf ein Drittel seiner Punkte reduziert werden. Gerade bei Bitmaps, die in Pfade umgewandelt wurden, oder sehr komplexen und detailreichen Grafiken kann sich das lohnen. Hier musst du natürlich sehr genau schauen, welche Details verzichtbar sind.

Zeichenfläche für „viewBox“ anpassen

Illustrator setzt für alle SVG-Dateien das „viewBox“-Attribut. Dieses sorgt dafür, dass eine SVG-Grafik unterschiedlich skaliert und beschnitten werden kann. Sinnvoll ist, wenn die Breite und Höhe der „viewBox“ identisch ist mit der Größe der Formen. Da die Maße der „viewBox“ aus der Zeichenfläche von Illustrator erzeugt werden, sollte die Zeichenfläche den darin platzierten Elementen entsprechen.

svg-optimieren_zeichenflaeche
Zeichenfläche an Objekte anpassen

Mit Illustrator kannst du die Zeichenfläche einfach anpassen, indem du im „Objekt“-Menü den Punkt „Zeichenflächen“ und „an ausgewählte Grafik anpassen“ auswählst. Andernfalls wird als „viewBox“ die automatisch vorgegebene oder manuell gesetzte Zeichenfläche verwendet. Im Normalfall ist dies das A4-Format.

Aussehen per Attribut oder Stylesheets bestimmen

Während Position und Größe einer Form immer über Attribute innerhalb des SVG-Elementes definiert werden, gibt es für das Aussehen unterschiedliche Möglichkeiten. So kannst du die Füllfarbe beispielsweise über das Attribut „fill“ direkt im Element definieren. Alternativ dazu kannst du ein Stilattribut verwenden. Hierbei bündelst du alle Angaben wie Füll- und Rahmenfarbe in einem „style“-Attribut.

<circle fill="#E1E04C" cx="75" cy="75" r="75"/>
<circle style="fill: #E1E04C;" cx="75" cy="75" r="75"/>

Als Letztes besteht die Möglichkeit, das Aussehen über ein eigenes Stilelement zu definieren. Der Vorteil hierbei besteht darin, dass Aussehen und Formelemente getrennt sind und das Aussehen per Klasse mehreren Elementen zugewiesen werden kann. Gerade bei komplexen Grafiken kann man sich so viel doppelten Quelltext sparen.

<style type="text/css">
 .st0 {fill:#E1E04C;}
</style>
<circle class="st0" cx="75" cy="75" r="75"/>

Für welche Möglichkeit du dich entscheidest, hängt von verschiedenen Faktoren ab – unter anderem davon, ob du per JavaScript das Aussehen dynamisch verändern möchtest. In diesem Fall bietet sich die Auszeichnung des Aussehens innerhalb des Elementes an.

svg-optimieren_stile
Auszeichnung des Aussehens festlegen

Kommentare entfernen und SVG komprimieren

Für den letzten Feinschliff solltest du etwaige Kommentare aus den SVG-Dateien entfernen. Gerade wenn du eine SVG-Datei generieren lässt, fügt die verwendete Anwendung gerne mindestens eine Kommentarzeile ein. Wer unnötigen Ballast grundsätzlich vermeiden möchte, wird hier sicher tätig werden.

Außerdem besteht die Möglichkeit, eine SVG-Datei per gzip zu komprimieren. Aus Illustrator heraus wird hierbei ein eigenes Dateiformat angeboten. Aber auch manuell kannst du eine SVG-Datei entsprechend komprimieren und mit der Endung „.svgz“ versehen. Der Browser entpackt die Datei automatisch.

5. Responsives SVG: Was geht, was geht nicht?

Im Webdesign sind responsive Layouts nicht mehr wegzudenken. Da gibt es auf der einen Seite immer mehr kleine Displays auf Smartphones und auf der anderen Seite immer größer werdende Monitore. Dazwischen finden sich Phablets, Tablets sowie Net- und Notebooks. Dank CSS ist es technisch kein Problem, eine Website für all die verschiedenen Auflösungen zu optimieren. Doch wie sieht es mit SVGs aus? Lassen sich diese auch responsiv gestalten?

Skalieren oder nicht skalieren?

Die einfachste Möglichkeit, eine SVG-Grafik auf verschiedenen Displays und Browserfenstern darzustellen, ist natürlich das Skalieren. Dabei wird die Grafik immer so vergrößert oder verkleinert, dass sie passt – mehr oder weniger jedenfalls.

Denn auch wenn einfaches Skalieren den wenigsten Aufwand mit sich bringt, hat es natürlich seine Nachteile. Gerade bei komplexen Grafiken gehen bei starken Verkleinerungen Details schon mal verloren oder sind kaum noch erkennbar. Texte können auf einmal so klein dargestellt sein, dass sie nicht mehr lesbar sind.

Während bei Fotos das einfache Skalieren meistens völlig in Ordnung ist, kommt es für vektorbasierte SVG-Formate mitunter nicht immer in Frage – jedenfalls nicht ausschließlich. Hier solltest du bei kleinen Darstellungen etwas optimieren, indem du zu kleine Elemente vergrößerst oder verzichtbare Details ausblendest.

<svg width="100%" height="100%">
  <rect x="50%" y="50%" width="150" height="150" style="transform: scale(0.5)" />
</svg>

Wichtig ist, dass die SVG-Grafik nicht per „img“ eingebunden wird, sondern direkt im HTML-Quelltext ausgezeichnet ist. Nur so hast du die Möglichkeit, über das Stylesheet des HTML-Dokumentes auch Eigenschaften deiner SVG-Elemente zu verändern.

Mit „viewBox“ skalieren

Im Normalfall werden die Elemente einer SVG-Zeichenfläche nicht skaliert, wenn du die Größe des „<svg>“-Elementes änderst. Sie behalten Position und Größe bei. Lediglich die Zeichenfläche wird nach rechts und unten vergrößert beziehungsweise verkleinert.

SVG ohne „viewBox“-Eigenschaft: Der Kreis bleibt immer gleich groß

Um eine Skalierung herbeizuführen, musst du die „viewBox“-Eigenschaft verwenden. Mit diesem Attribut definierst du einen Ausschnitt der SVG-Zeichenfläche, der immer die gesamte Zeichenfläche des „<svg>“-Elementes ausfüllt.

<svg width="100%" height="100%" viewBox="0 0 300 300">
  <circle cx="150" cy="150" r="150" />
</svg>

Ändert sich dann die Größe der Zeichenfläche, wird auch der gesamte Inhalt skaliert. So kannst du für jede SVG-Grafik stets entscheiden, wie sie sich verhalten soll.

Größen- und Positionsangaben per CSS ändern

Egal, ob du dich für oder gegen das Skalieren entschieden hast: In jedem Fall sollte geprüft werden, ob bei besonders kleinen Darstellungen Optimierungsbedarf besteht.

SVG ohne „viewBox“-Eigenschaft: Der Kreis skaliert mit der Zeichenfläche

Wird nicht skaliert, kann es dir zum Beispiel passieren, dass die Grafik nicht mehr in die Zeichenfläche passt und am rechten Rand verschwindet. Bei Skalierungen hingegen solltest du prüfen, ob alle Formen und Texte noch gut erkennbar sind.
Bei Bedarf sollten Größe und Position der Formen verändert werden.

Hier hast du schon gleich das erste Problem: Denn Größe und Position von SVG-Grafiken werden nicht per CSS gesteuert, sondern per Attribut der jeweiligen Elemente. Das bietet dir lediglich die Möglichkeit, per “transform”-Eigenschaft Einfluss zu nehmen, auf Größe und Position.

CSS-Transformationen für SVG-Formen

Zunächst einmal werden Größe und Position also über die SVG-Auszeichnung als Attribute angegeben. Damit bleiben dir nur die CSS-Funktionen „translate()“ und „scale()“, um einzelne Formen eines SVGs zu verändern.

Der Nachteil dieser Möglichkeit ist, dass nur relative Änderungen möglich sind. Aber auf diese Weise hast du zumindest die Möglichkeit, Optimierungen vorzunehmen. So kannst du zum Beispiel die Größenverhältnisse einzelner Formen anpassen. Gerade bei kleinen Darstellungen hilft es schon mal, besonders kleine Formen etwas zu vergrößern.

Rahmen und Schrift anpassen

Gänzlich unproblematisch ist es, die Rahmenstärke und Schriftgröße anzupassen. Diese Angaben werden auch beim SVG-Format per CSS definiert.

Wird eine SVG-Grafik auf Mobilgeräten herunterskaliert, bietet es sich gegebenenfalls an, die Rahmenstärke und die Schriftgröße zu erhöhen. So verhindert man, dass Rahmen kaum oder nur sehr dünn erscheinen und Schrift schlecht lesbar ist.

circle {
  stroke-width: 3px;
}
text {
  font-size: 20px;
}

Auch Angaben zur Füll- und Konturfarbe werden per CSS ausgezeichnet, so dass diese Anpassungen ganz problemlos gemacht werden können. Allerdings dürften solche Anpassungen bei responsiven Layouts eher seltener eine Rolle spielen.

Relative Angaben bei Attributen machen

Da also Positionsangaben per CSS nicht ohne weiteres geändert werden können, bietet es sich gegebenenfalls an, Formen statt mit absoluten Werten besser relativ zu platzieren. Gerade wenn es darum geht, Elemente auf einer Zeichenfläche zu verteilen, bietet sich dies an.

Vor allem, wenn sich bei einer SVG-Grafik ohne „viewBox“-Angabe die Breite oder Höhe ändert, lassen sich per relativer Angabe Elemente immer gleichmäßig auf der Zeichenfläche verteilen.

Rechteck per „x“- und „y“-Attribute auf je 50 Prozent platziert

In Kombination mit der CSS-Funktion „translate()“ hast du zudem die Möglichkeit, Elemente immer mittig zu platzieren. So kannst du ein eine Form per „x“- und „y“-Attribute mittig platzieren, indem du jeweils den Wert „50%“ vorgibst. Jetzt ist aber erst einmal nur die linke obere Ecke mittig platziert.

<svg width="100%" height="100%" viewBoxx="0 0 300 300">
  <rect x="50%" y="50%" width="150" height="150" style="transform: translate(-75px, -75px)" />
</svg>

Um die Form als solche mittig zu platzieren, verschiebst du die Form per “translate()” um je die Hälfte der Breite und Höhe nach links beziehungsweise rechts. So erreichst du, dass eine Forme auch bei relativer Angabe immer zentriert dargestellt wird.

Relative Platzierung mit zusätzlichem „translate()“

6. Warum du SVG inline einbinden solltest

Wer mit SVG-Grafiken arbeitet, hat gleich mehrere Möglichkeiten, diese in ein HTML-Dokument einzubinden. Neben der Verwendung als klassische Bilddatei über das „<img>“-Element lassen sich SVG auch per „<object>“ oder „<iframe>“ implementieren. Letztere haben den Vorteil, dass auch JavaScript und Animationen ausgeführt werden können. Die einfache Variante ist jedoch, SVG inline im HTML-Quelltext auszuzeichnen. Dies erlaubt dir einen einfachen Umgang und Zugriff auf SVG-Formen per CSS und JavaScript.

SVG inline: Kein zusätzlicher Request

Zunächst einmal verursachen Inline-SVGs keinen zusätzlichen Request, da sie Teil des HTML-Dokumentes sind. Gerade bei vielen kleinen SVGs auf einer Seite kann sich das bemerkbar machen.

Werden dieselben Grafiken jedoch in mehreren Dokumenten verwendet, bietet sich gegebenfalls an, diese extern einzubinden. Mit entsprechenden Chache-Einstellungen müssen die Grafiken dann nicht bei jedem zu ladenden Dokument ebenfalls neu geladen werden.

Einheitliche Styles

Ein ganz anderer, äußerst praktischer Vorteil von Inline-SVGs ist jedoch die Möglichkeit, das Aussehen der Grafiken über die Stylesheets des HTML-Dokumentes zu steuern.

Füll- und Linienfarbe lassen sich ebenso definieren wie beispielsweise Linienstärke und Transformationen. Dabei zeichnest du SVG-Stylesheets genau so aus wie HTML-Stylesheets und kannst auch HTML- und SVG-Selektoren miteinander kombinieren.

article svg rect {
  fill: red;
}
asidesvg rect {
  fill: green;
}

Im Beispiel wird die Füllfarbe eines SVG-Rechteckes in Abhängigkeit vom elterlichen HTML-Element vergeben. Ist dieses ein „<article>“-Element, wird es rot, ist es ein „<aside>“-Element, wird es grün gefärbt.

Hover-Effekte

Auch Hover-Effekte erstellst du auf diese Weise ganz unkompliziert. So kannst du beispielsweise SVGs innerhalb eines Links platzieren und per CSS einen Hover-Effekt generieren.

<a href="http://www.example.com/">
  <svg>
    <rect x="0" y="0" width="15" height="15" />
  </svg>
</a>

Sowohl das Aussehen des SVG-Rechteckes als auch das Hover-Verhalten definierst du per Stylesheets.

a svg rect {
  background: red;
  transition: all 0.5s ease;
}
a:hover svg rect {
  transform: rotateX(90deg);
}

Im Bespiel wird eine SVG-Grafik innerhalb eines „<a>“-Elementes platziert und anschließend per CSS gestaltet. Ein Hover-Effekt auf das „<a>“-Element sorgt dafür, dass das Rechteck um 90 Grad gedreht wird.

Ein solches Verhalten ist über eine externe Referenzierung nicht möglich. Über das „<img>“-Element eingebundene SVG-Dateien lassen keine Veränderung per CSS zu und per „<object>“ referenzierte Dateien lassen sich nur über Umwege in Kombination per JavaScript verändern.

Einfacherer Zugriff per JavaScript

Da sich eingebundene SVG-Grafiken innerhalb des DOM-Knotenbaums des HTML-Dokumentes befinden, ist nicht nur der Zugriff per CSS auf einzelne Elemente möglich. Auch per JavaScript kannst du ganz bequem auf einzelne SVG-Elemente zugreifen.

Bei per „<object>“ eingebundenen SVG-Dateien ist der Zugriff per JavaScript nur über die Eigenschaft „contentDocument“ möglich. Diese erlaubt es, auf den DOM-Baum externer Dateien zuzugreifen.

document.getElementsByTagName("object")[0].contentDocument.getElementsByTagName("rect")[0].setAttribute("class", "hover");

Im Beispiel wird per „contentDocument“ auf ein Element innerhalb einer per „<object>“ referenzierten SVG-Datei zugegriffen.

Ist die SVG-Grafik direkt im HTML-Dokument ausgezeichnet, kannst du auf einzelne SVG-Elemente so zugreifen, wie du auch auf HTML-Elemente zugreifen würdest.

document.getElementsByTagName("rect")[0].setAttribute("class", "hover");

Im zweiten Beispiel greifst du einfach auf das erste „rect“-Element zu, welches in deinem HTML-Dokument ausgezeichnet ist.

Zwischenfazit

Inline-SVGs haben viele Vorteile gegenüber extern eingebundener SVG-Dateien. Vor allem das Zusammenspiel mit CSS funktioniert wesentlich einfacher, da du SVG per CSS so behandeln kannst wie alle anderen Elemente deines Dokumentes. Gerade für Interaktionen wie Hover-Effekte ist das ein entscheidender Vorteil.

7. SVG: So arbeitest du mit Texten und Schrift

Das SVG-Format eignet sich nicht nur zur Darstellung vektorbasierter Formen. Auch Schrift kannst du darin platzieren und gestalten. Im Gegensatz zur semantischen Schriftauszeichnung in HTML gibt es mit SVG einige Besonderheiten und Eigenarten zu berücksichtigen. Auch hinsichtlich der Gestaltung von Schrift per CSS solltest du einige Unterschiede kennen.

Schrift per SVG auszeichnen und mit CSS gestalten

Während HTML gleich mehrere semantische Elemente kennt, mit denen du Text als Überschrift, Absatz, Liste oder Tabelle auszeichnen kannst, kennt das SVG-Format lediglich das „<text>“-Element. Innerhalb dieses Elementes kannst du Schrift platzieren und diese gestalten.

<text>Lorem ipsum.</text>

Die Gestaltung des Textes erfolgt wie bei HTML mit CSS. Du kannst Webschriften einbinden und dern Schriftart, -größe sowie die Ausrichtung festlegen. Während Schriftart und -größe mit den bekannten Eigenschaften „font-family“ und „font-size“ definiert werden, gibt es für die Ausrichtung die Eigenschaft „text-anchor“ mit den Werten „start“ für linksbündigen, „end“ für rechtsbündigen und „middle“ für zentrierten Text.

text {
  font-family: "Source Sans";
  font-size: 30px;
  text-anchor: middle;
}

Da SVG keinen klassischen mehrzeiligen Text kennt, ist die Angabe eines Zeilenabstandes überflüssig. Wie alle anderen SVG-Elememte, wird auch das „<text>“-Element per „x“ und „y“ platziert. Der „y“-Wert definiert bei Texten allerdings deren Grundlinie. Bei einem Text, dem der Wert 0 für die „y“-Eigenschaft zugewiesen wurde, verschwindet der Text aus dem oberen Bildrand.

SVG: Mehrzeiligen Text erstellen

Die SVG-Syntax kennt kein Element wie „<br>“, um einen Zeilenumbruch innerhalb eines Textes herbeizuführen. Allerdings gibt es das „<tspan>“-Element, mit dem du einen Text unterteilen und individuell anordnen kannst.

<text>
  <tspan>Lorem ipsum.</tspan>
  <tspan>Lorem ipsum.</tspan>
</text>

Standardmäßig werden die einzelnen „<tspan>“-Elemente nebeneinander angeordnet, ähnlich wie beim „<span>“-Element in HTML. Die Platzierung von SVG-Elementen erfolgt mit den Eigenschaften „x“ und „y“. Die beiden Eigenschaften sorgen allerdings für eine absolute Positionierung von Elementen. Das heißt, die einzelnen „<tspan>“-Elemente werden weder in Relation zum übergeordneten „<text>“-Element noch zu anderen „<tspan>“-Elementen platziert.

text-schrift-svg_tspan1
Standardmäßig angeordnete „<tspan>“-Elemente

Allerdings stehen für „<tspan>“ die speziellen Eigenschaften „dx“ und „dy“ zur Verfügung. Diese sorgen für eine relative Platzierung zum jeweils zuvor ausgezeichneten „<tspan>“-Element.

text-schrift-svg_tspan2
„<tspan>“-Elemente, die per „dx“ und „dy“ platziert wurden

Mit „dy“ kannst du also den Zeilenabstand einzelner „<tspan>“-Elemente definieren. Da auch „dx“ relativ zum zuvor definierten „<tspan>“-Element ist, musst du für die vertikale Platzierung „x“ verwenden.

<text>
  <tspan x="0" dy="0">Lorem ipsum.</tspan>
  <tspan x="0" dy="36px">Lorem ipsum.</tspan>
  <tspan x="0" dy="36px">Lorem ipsum.</tspan>
</text>

Mit diesem Beispiel sorgst du dafür, dass alle Textzeilen auf der X-Koordinaten bei 0 beginnen und auf der Y-Koordinaten um jeweils 36 Pixel je Zeile nach unten verschoben werden.

text-schrift-svg_tspan3
„<tspan>“-Elemente, die per „x“ und „dy“ platziert werden

SVG: Text an Pfad ausrichten

Ein Vorteil des SVG-Formates im Vergleich zu HTML, ist die Möglichkeit, per SVG einen Text an einem Pfad ausrichten zu lassen. So kannst du einen Text zum Beispiel entlang einer Kreisbahn platzieren. Hierzu verwendest du das „<textPath>“-Element.

Dazu muss zunächst ein Pfad definiert werden, an dem sich der Text orientieren soll. Hier ist es zwingend erforderlich, dass du diesen Pfad per „<path>“-Element erstellst. Auch wenn der Text an einem Kreis ausgerichtet werden soll, darfst du diesen Kreis nicht per „<circle>“ auszeichnen. „<textPath>“ erlaubt, wie der Name erahnen lässt, ausschließlich Pfadelemente.

<defs>
  <path id="textpfad" cd="M200,125c0,41.4-33.6,75-75,75s-75-33.6-75-75s33.6-75…" />
</defs>

Im Beispiel zeichnen wir einen Kreis per „<path>“. Da der Kreis selbst nicht sichtbar sein soll, kannst du ihn innerhalb des „<defs>“-Bereichs auszeichnen. Außerdem musst du dem Pfad eine ID zuweisen.

text-schrift-svg_textpath
An einem Kreispfad ausgerichteter Text

Anschließend wird das „<textPath>“-Element zwischen dem „<text>“- und dem „<tspan>“-Element platziert. Über die ID des Pfades wird dieser zugewiesen.

<text>
  <textPath xlink:href="#textpfad" startOffset="50%">
    <tspan >Lorem ipsum.</tspan>
  </textPath>
</text>

Mit der Eigenschaft „startOffset“ bestimmst du, an welcher Position auf dem Pfad der Text beginnen soll. Erlaubt sind absolute und prozentuale Angaben.

Schriften in SVG einbetten

Neben der Möglichkeit, Webschriften per CSS einzubinden, lassen sich Schriften in SVG auch einbetten. Dazu stehen die Elemente „<font>“ und „<glyph>“ zur Verfügung. Per „<font>“ wird eine Schriftart definiert. Jedes Zeichen der Schrift wird mit „<glyph>“ ausgezeichnet. Die Kontur der Schrift hinterlegen wir als Pfad.

Wenn du aus Illustrator heraus SVG-Dateien erzeugst, kannst du Schriften auf diese Weise einbetten. Dies bietet sich an, wenn du eine SVG-Datei benötigst, die ohne Verweise auf externe Dateien auskommt. Da eingebettete Schriften im Vergleich zu Webfonts zu größeren Dateien führen, solltest du vorzugsweise auf die Einbindung mit Stylesheets setzen.

8. So erstellst du interaktive Grafiken für deine Website

Dass das SVG-Format weit mehr ist als ein vektorbasiertes Grafikformat, dürfte inzwischen bekannt sein. Animationen und Interaktionen gehören ebenfalls zum Repertoire des Vektorformats. Da auch JavaScript innerhalb einer SVG-Datei eingesetzt werden kann, ergeben sich zahlreiche Anwendungsmöglichkeiten. Die JavaScript-Lösung svidget.js stellt hierfür ein umfangreiches Framework zur Verfügung, welches das Erstellen und Einbinden von SVG-Grafiken in Form von Widgets ermöglicht.

SVG-Widgets erstellen und einbinden

SVG-Widgets sind zunächst einmal klassische SVG-Dateien, die dank des Frameworks von svidget.js um zusätzliche Elemente erweitert werden, mit denen sich das Aussehen einer Grafik beeinflussen lässt. Zusätzlich erlaubt das Framework, Aktionen und Ereignisse zu definieren. Die SVG-Widgets werden über das „<object>“-Element in ein HTML-Dokument eingebunden und können dann per „<parameter>“-Element konfiguriert werden. Wie sich die per „<parameter>“ gemachten Angaben auf die SVG-Datei auswirken, wird innerhalb der SVG-Datei festgelegt.

Damit das Framework funktioniert, musst du die JavaScript-Datei „svidget.js“ sowohl in dein HTML-Dokument als auch in die jeweilige SVG-Datei einbinden.

Parameter in SVG-Datei festlegen

Mit svidget.js ist es beispielsweise möglich, ein und dieselbe SVG-Datei mit unterschiedlichem Aussehen in ein und dasselbe HTML-Dokument einzubinden. Dabei wird innerhalb der SVG-Datei festgelegt, welche Parameter berücksichtigt werden sollen.

<svidget:params>
  <svidget:param name="backgroundColor" type="string" subtype="color" binding="#elementA@fill" />
  <svidget:param name="borderColor" type="string" subtype="color" binding="#elementB@stroke" />
  <svidget:param name="borderWidth" type="number" binding="#elementA@stroke-width, #elementB@stroke-width" />
</svidget:params>

Innerhalb des Elementes „<svidget:params>“ legst du einzelne Parameter per „<svidget:param>“ fest. Diese interpretieren später die Angaben, die du in den „<parameter>“-Elementen des einbindenden HTML-Dokumentes gemacht hast. Neben der Angabe eines Namens wird mit „type“ und „subtype“ vorgegeben, was für ein Wert erwartet wird. Die ersten beiden Angaben im Beispiel erwarten eine Zeichenkette, die eine Farbe beschreiben muss, die dritte Angabe eine Zahl.

Über „binding“ legst du fest, was mit dem Wert geschehen soll. Die Zeichenkette vor dem @-Zeichen beschreibt die ID der SVG-Form und die Zeichenkette danach das Attribut der Form, die den Wert erhalten soll. Der Wert „#elementA@fill“ weist somit der „fill“-Eigenschaft der Form mit der ID „elementA“ die Farbe zu, die per „backgroundColor“ definiert wurde.

Zu guter Letzt musst du noch die JavaScript-Datei einbinden.

<script type="application/javascript" xlink:href="svidget.js"></script>

SVG-Widget in HTML-Dokument einbinden

Im nächsten Schritt baust du die SVG-Datei in ein HTML-Dokument ein. Hierzu verwendest du das „<object>“-Element.

<object data="star.svg" role="svidget" id="star" type="image/svg+xml" width="200" height="200">
  <param name="borderColor" value="red" />
  <param name="backgroundColor" value="green" />
  <param name="borderWidth" value="3" />
</object>

Über die Eigenschaft „data“ wird die SVG-Datei referenziert. Wichtig ist, dass per „role“ der Wert „svidget“ angegeben wird. Nur so weiß das Framework, dass die SVG-Datei auch als SVG-Widget behandelt werden soll. Über die „<param>“-Elemente kannst du nun die Hintergrundfarbe sowie Rahmenfarbe und -stärke angeben. Die Namen für die einzelnen „<param>“-Elemente müssen den Namen der jeweiligen „<svidget:param>“-Namen in der SVG-Datei entsprechen.

svidgetjs_stern1
Aussehen des Sterns per „<param>“-Elemente geändert

Aktionen festlegen

Für Interaktivität sorgen die Aktionen, die du mit den Elementen „<svidget:actions>“ und „<svidget:action>“ definieren kannst.

<svidget:actions>
  <svidget:action name="backgroundColorChange" binding="changeBackgroundColor">
    <svidget:actionparam name="newBackgroundColor" type="string" subtype="color" />
  </svidget:action>
</svidget:actions>

Im Beispiel wird die Aktion „backgroundColorChange“ definiert. Über „binding“ habe ich den Namen einer Funktion angegeben, die ausgeführt werden soll, sobald über das HTML-Dokument diese Aktion aufgerufen wird. Über „<svidget:actionparam>“ definiert man Parameter, die per JavaScript im HTML-Dokument an das SVG-Widget übergeben werden.

function changeBackgroundColor(newBackgroundColor) {
  svidget.current().param("backgroundColor").value(newBackgroundColor);
}

Die Funktion „changeBackgroundColor()“ innerhalb der SVG-Datei ändert die Hintergrundfarbe des SVG-Widgets mit dem über „newBackgroundColor“ übergebenen Wert.

Innerhalb des HTML-Dokumentes legst du einen Event-Listener an, der per Klick auf ein Element die Aktion im SVG-Widget aufruft.

document.getElementById("button").addEventListener("click", function() {
 svidget.widget("star").action("backgroundColorChange").invoke("red");
}, false);

Im Beispiel wird per Klick auf das Element mit der ID „button“ innerhalb des SVG-Widgets mit der ID „star“ die Aktion „backgroundColorChange“ aufgerufen. Per „invoke()“ wird ein Wert – in diesem Fall die Farbangabe „red“ – übergeben. Die Funktion „changeBackgroundColor()“ innerhalb der SVG-Datei sorgt nun dafür, dass der Parameter „backgroundColor“ über den Buttonklick auf den Wert „red“ geändert wird.

svidgetjs_stern2
Aussehen des Sterns nach der Aktion „backgroundColorChange“

Ereignisse festlegen

Eine weitere Funktionalität von svidget.js ist es, Ereignisse zu definieren. Damit ist es möglich, über das HTML-Dokument auf ein Ereignis in der SVG-Datei zu reagieren. Dazu muss, ähnlich wie bei den Aktionen innerhalb der SVG-Datei, ein Ereignis per „<svidget:events>“ und „<svidget:event>“ angelegt werden.

<svidget:events>
  <svidget:event name="changeComplete" />
</svidget:events>

Anschließend muss innerhalb der SVG-Datei noch irgendwo festgelegt werden, wann dem HTML-Dokument mitgeteilt werden soll, dass das Ereignis eingetroffen ist. Das kann beispielsweise innerhalb der Funktion „changeBackgroundColor()“ erfolgen.

function changeBackgroundColor(newBackgroundColor) {
  svidget.current().param("backgroundColor").value(newBackgroundColor);
  svidget.current().event("changeComplete").trigger();
}

Die zusätzliche Zeile sorgt dafür, dass per „trigger()“ das Ereignis „changeComplete“ ausgelöst wird. Innerhalb der HTML-Datei musst du nun noch festlegen, was dort passieren soll, wenn das Ereignis vom SVG-Widget ausgelöst wurde.

svidget.loaded(function (e) {
  svidget.widget("star").event("changeComplete").on(function() {
    console.log("Fertig!");
  });
});

Im Beispiel wird beim Ereignis einfach eine Funktion aufgerufen, die etwas in die Konsole des Browsers schreibt. Sobald also in der SVG-Datei die Funktion „changeBackgroundColor()“ ausgeführt wird, schreibt das HTML-Dokument per „console.log()“ etwas in die Konsole.

Anwendungsmöglichkeiten

Die hier vorgestellten Möglichkeiten stellen nur einen kleinen Ausschnitt des weit größeren Funktionsumfangs von svidget.js dar. Das Framework eignet sich prima, um zum Beispiel Diagramme per SVG darzustellen. Innerhalb der SVG-Datei können die Formen für ein Torten- oder Balkendiagramm festgelegt werden. Über die Parameter lassen sich dann die Werte und Bezeichnungen übergeben. Dieselbe SVG-Datei kann somit verschieden dargestellt werden.

svidgetjs_beispiele

Es gibt eine umfangreiche Dokumentation, sowie zahlreiche Beispiele, die auch die unterschiedlichen Anwendungsmöglichkeiten von svidget.js widerspiegeln. Das Framework steht unter der gängigen MIT-Lizenz zur kostenlosen Verwendung, auch zu kommerziellen Zwecken, zur Verfügung und kommt ohne zusätzliche JavaScript-Bibliotheken aus.

9. So funktioniert die Eigenschaft viewBox

Dank der XML-Syntax lassen sich SVG-Grafiken auch per Editor erstellen. In vielen SVG-Quelltexten findet man das „viewBox“-Attribut innerhalb des „<svg>“-Elementes. Was hat es mit diesem Attribut auf sich? Was macht es und wozu braucht man es?

Definition von Höhe und Breite einer Grafik

Die Maße einer Grafik im SVG-Format werden über die „width“- und „height“-Attribute angegeben. Werden diese nicht definiert, ergibt sich die Größe aus den erstellten Formen.

<svg width="300" height="300">
  <circle cx="75" cy="75" r="75" fill="red" />
  <circle cx="75" cy="225" r="75" fill="blue" />
  <circle cx="225" cy="75" r="75" fill="green" />
  <circle cx="225" cy="225" r="75" fill="white" />
</svg>

svg_viewport_1

Im Beispiel wird eine SVG-Zeichenfläche mit 300 Pixel Kantenlänge definiert. Darin werden vier Kreis gezeichnet, welche die Zeichenfläche ausfüllen. Mit dem „viewBox“-Attribut ist es nun möglich, für die Zeichenfläche ein eigenes Koordinatensystem festzulegen. Das Attribut erwartet vier Werte: eine X- und Y-Koordinate, die den Ursprung des Koordinatensystem angeben sowie eine Breiten- und Höhenangabe für die Größe des Systems.

<svg width="300" height="300" viewBox="0 0 300 300">
  <circle cx="75" cy="75" r="75" fill="red" />
  …
</svg>

Die „viewBox“-Eigenschaft im Beispiel entspricht der Darstellung ohne „viewBox“-Attribut. Vergrößert man nun das „viewBox“-Koordinatensystem, führt das dazu, dass alle darin definierten Formen kleiner angezeigt werden.

<svg width="300" height="300" viewBox="0 0 600 600">
  <circle cx="75" cy="75" r="75" fill="red" />
  …
</svg>

svg_viewport_2

Alle Positions- und Größenangaben der „<circle>“-Elemente im Beispiel beziehen sich auf das per „viewBox“ definierte Koordinatensystem. Dieses Koordinatensystem wird auf die per „width“ und „height“ angegebene Größe skaliert. Im vorliegenden Fall bedeutet es eine Skalierung auf 50 Prozent.

SVG-Formen skalieren und verschieben

Das „viewBox“-Attribut bietet sich also an, um alle Formen, die innerhalb eines „<svg>“-Elementes angelegt sind, beliebig zu vergrößern oder verkleinern – ohne, dass im Beispiel die Attribute der „<circle>“-Elemente selbst verändert werden müssen. Verkleinert man die Breite und Höhe des „viewBox“-Zeichensystems, führt es zu einer vergrößerten Darstellung der Kreise.

Die Skalierung der Zeichenfläche erfolgt übrigens immer proportional, auch wenn die Breiten- und Höhenangabe in der „viewBox“-Eigenschaft nicht proportional zur Breite und Höhe der „<svg>“-Elementes definiert sind. Als Basis für die Skalierung wird der jeweils größere Wert verwendet. Der andere Wert beeinflusst dann die Platzierung der Elemente innerhalb der Zeichenfläche

<svg width="300" height="300" viewBox="0 0 300 600">
  <circle cx="75" cy="75" r="75" fill="red" />
  …
</svg>

svg_viewport_3

Im Beispiel werden alle Elemente um 50 Prozent verkleinert dargestellt. Diese werden dann allerdings nicht links oben platziert, sondern zentriert am oberen Rand.

Mit den ersten beiden Werten der „viewBox“-Eigenschaft ist es zudem möglich, alle Inhalte der Zeichenfläche zu verschieben, indem ein anderer Ursprung für das Koordinatensystem festgelegt wird.

<svg width="300" height="300" viewBox="-75 75 300 300">
  <circle cx="75" cy="75" r="75" fill="red" />
  …
</svg>

svg_viewport_4

Im Beispiel wird der Nullpunkt des Koordinatensystems um 75 Pixel nach rechts und 75 Pixel nach oben verschoben. Die vier Kreise werden im Beispiel entsprechend nach rechts und oben versetzt.

Automatische Anpassung

Das „viewBox“-Attribut kann ebenfalls verwendet werden, wenn der Inhalt einer SVG-Grafik immer an das jeweilige Elternformat beziehungsweise das Browserfenster angepasst werden soll. Dazu werden die „viewBox“-Werte so gesetzt, dass der Ursprung bei jeweils Null und die Breiten- und Höhenangabe dem Außenmaß der Formen entsprechen – im Beispiel je 300 Pixel. Die „width“- und „height“-Werte des „<svg>“-Elementes werden auf 100 Prozent gesetzt.

<svg width="100%" height="100%" viewBox="0 0 300 300">
  <circle cx="75" cy="75" r="75" fill="red" />
  …
</svg>

svg_viewport_5

Öffnet man die SVG-Grafik im Browser, wird die Grafik auf die komplette Größe des Fensters skaliert. Die Inhalte werden jedoch nicht verzerrt dargestellt, sondern werden so vergrößert beziehungsweise verkleinert, dass sie entweder die Breite oder Höhe des Fensters ausfüllen – aber ohne beschnitten zu werden.

Denselben Effekt erzielt man auch, wenn die Grafik innerhalb eines anderen Elementes mit definierter Größe platziert wird.

10. Animiertes SVG-Morphing mit Illustrator

Das SVG-Format löst mehr und mehr Flash für vektorbasierte und animierte Grafiken ab. Aufgrund der XML-Syntax des SVG-Formates lassen sich Grafiken im Grunde per Texteditor erstellen, was in den meisten Fällen jedoch wenig sinnvoll ist. Denn Zeichenprogramme wie Illustrator verfügen über die Möglichkeit, Grafiken ins SVG-Format zu exportieren. Animationen lassen sich damit allerdings nicht umsetzen, so dass hier doch der Texteditor zu Hilfe genommen werden muss. Allerdings ist es relativ einfach, mit Illustrator und einem Texteditor eine SVG-Grafik in Bewegung zu bringen – zum Beispiel als Morphing-Animation.

Formen in Illustrator zeichnen

Ein bewegtes Morphing entsteht, indem eine Zeichenform in eine andere Zeichenform animiert wird. Dazu müssen beide Formen zunächst in Illustrator angelegt werden. Wichtig ist, dass beide Formen mit demselben SVG-Element ausgezeichnet werden – zum Beispiel „<polygon>“ für einfache mehreckige Formen oder „<path>“ für komplexe Formen mit Kurven und Aussparungen. Auch die Anzahl der Koordinaten beziehungsweise Kurven müssen jeweils übereinstimmen. Ansonsten lassen sich die Transformationen nicht animieren.

Im Beispiel legen wir in Illustrator einen fünfzackigen Stern an und exportieren diesen als SVG-Datei. Anschließend ändern wir die Koordinaten des Sterns so, dass daraus ein Zehneck wird. Dieses Zehneck wird ebenfalls als SVG-Datei gespeichert. In beiden Grafiken sind jeweils zehn Koordinaten angegeben. Statt die Koordinaten zu ändern, kann man natürlich auch eine gänzlich neue Form zeichnen, solange diese dieselbe Anzahl von Koordinaten aufweist.

svg-illustrator-export
SVG-Optionem beim Speichern in Illustrator

Illustrator wird sowohl den Stern als auch das Zehneck jeweils als „<polygon>“-Element in der SVG-Datei auszeichnen. Sobald Bézierkurven oder verknüpfte Pfade zum Einsatz kommen, wird die Form als „<path>“-Element exportiert. Hier muss man einfach darauf achten und sich das exportierte Ergebnis einmal ansehen.

Formen zusammenbringen und animieren

Illustrator hat seine Arbeit für die animierte Form nun getan. Ab sofort wird mit dem Texteditor weitergearbeitet. Dort wird die erste SVG-Datei geöffnet und das entsprechende „<polygon>“-Element gesucht. Es besitzt eine „fill“-Eigenschaft, welche die Füllfarbe definiert, sowie eine „point“-Eigenschaft mit den zehn Koordinaten-Paaren bestehend aus jeweils einer X- und einer Y-Koordinate.

<polygon fill="#FF8200" points="47.6,4.8 62.2,34.5 95.1,39.3 71.3,62.5 76.9,95.2 47.6,79.8 18.2,95.2 23.8,62.5 0,39.3 32.9,34.5" />

Zum Animieren von Formen gibt es das „<animate>“-Element, welches das jeweilige Elternelement in Bewegung versetzt. Daher muss es als Kindelement des Polygons im Quelltext platziert werden.

<polygon fill="#FF8200" points="47.6,4.8 62.2,34.5 95.1,39.3 71.3,62.5 76.9,95.2 47.6,79.8 18.2,95.2 23.8,62.5 0,39.3 32.9,34.5">
  <animate attributeName="points" to="47.6,0 76.9,9.5 95.1,34.5 95.1,65.5 76.9,90.5 47.6,100 18.2,90.5 0,65.5 0,34.5 18.2,9.5" dur="500ms" repeatCount="indefinite" />
</polygon>

Das „<animate>“-Element besitzt mindestens drei Eigenschaften. Mit „attributeName“ wird die Eigenschaft des Elternelements angegeben, die per Animation verändert werden soll. In unserem Beispiel ist es das „point“-Element des Polygons. Die Eigenschaft „to“ enthält den Zielwert für die Eigenschaft, die per „attributeName“ angegeben ist. In diesem Fall sind es also die Koordinaten des Zehnecks. Dazu kopieren wir die Koordinaten – also den Wert des „point“-Attributes der zweiten SVG-Datei – und weisen sie der „to“-Eigenschaft als Wert zu.

svg-morphing-schritte
Animationsablauf vom Stern zum Zehneck

Während das „<polygon>“-Element in der „point“-Eigenschaft also die Koordinaten für den Stern hat, besitzt das „<animate>“-Element in der „to“-Eigenschaft die Koordinaten des Zehnecks. Per „dur“-Eigenschaft wird noch die Dauer der Animation angegeben. Ruft man die SVG-Datei im Browser auf, wird der Stern innerhalb einer halben Sekunde in ein Zehneck verwandelt. Will man die Animation mehrmals oder dauerhaft ausführen, gibt man über die Eigenschaft „repeatCount“ die Anzahl der Wiederholungen oder „indefinite“ für dauerhafte Wiederholungen an.

Hin und zurück animieren

In unserem Beispiel wiederholt sich die Transformation vom Stern zum Zehneck zwar dauerhaft. Allerdings findet keine Animation vom Zehneck zurück zum Stern statt. Will man eine rückläufige Animation ergänzen, um jeweils fließend ins Zehneck und wieder zurück zum Stern zu transformieren, muss die „<animate>“-Eigenschaft etwas verändert werden.

Statt der „to“-Eigenschaft, welche nur ein Ziel für eine Animation beinhaltet, wird die „values“-Eigenschaft verwendet. Der Vorteil von „values“ ist, dass dort beliebig viele Animationsschritte hinterlegt werden können. Per Semikolon voneinander getrennt, lassen sich also beliebige viele Koordinaten für das „<polygon>“-Element angeben. Diese werden nacheinander abgearbeitet und somit animiert.

Für unser Beispiel müsen per „values“-Eigenschaft drei Animationsschritte angegeben werden. Als erster und letzter Wert für „values“ werden die Koordinaten des Sterns verwendet. Als zweiter Wert werden die Koordinaten des Zehneckes angegeben.

<polygon fill="#FF8200" points="47.6,4.8 62.2,34.5 95.1,39.3 71.3,62.5 76.9,95.2 47.6,79.8 18.2,95.2 23.8,62.5 0,39.3 32.9,34.5">
  <animate attributeName="points" values="[Sternkoordinaten]; [Zehneckkoordinaten]; [Sternkoordinaten]" dur="500ms" repeatCount="indefinite" />
</polygon>

Da Start- und Endpunkt für die Animation jeweils die Koordinaten des Sterns sind, endet und beginnt die Animation jeweils mit derselben Form.

Animation per Klick starten

Mit einer weiteren Eigenschaft kann man die Animation erst dann beginnen lassen, wenn die Form angeklickt wird. Dazu muss einfach die Eigenschaft „begin“ mit dem Wert „click“ ergänzt werden.

<polygon fill="#FF8200" points="47.6,4.8 62.2,34.5 95.1,39.3 71.3,62.5 76.9,95.2 47.6,79.8 18.2,95.2 23.8,62.5 0,39.3 32.9,34.5">
  <animate begin="click" attributeName="points" values="[Sternkoordinaten]; [Zehneckkoordinaten]; [Sternkoordinaten]" dur="500ms" repeatCount="indefinite" />
</polygon>

Mehr Möglichkeiten hat man, wenn man JavaScript zur Steuerung der Animation einsetzt. So ist es möglich, per Klick die Animation zum Zehneck und per weiterem Klick die Animation zurück zum Stern zu starten. Dazu müssen zwei verschiedene „<animate>“-Elemente definiert werden. Das erste Element enthält die Koordinaten zum Zehneck, das zweite die Koordinaten zum Stern. Da jeweils nur ein Zielwert für die Animation pro „<animate>“-Element angegeben wird, verwenden wir wieder die „to“-Eigenschaft.

<polygon fill="#FF8200" points="47.6,4.8 62.2,34.5 95.1,39.3 71.3,62.5 76.9,95.2 47.6,79.8 18.2,95.2 23.8,62.5 0,39.3 32.9,34.5">
  <animate attributeName="points" to="[Zehneckkoordinaten]" dur="500ms" begin="indefinite" fill="freeze" />
  <animate attributeName="points" to="[Sternkoordinaten]" dur="500ms" begin="indefinite" fill="freeze" />
</polygon>

Außerdem wird der Eigenschaft „begin“ der Wert „indefinite“ zugewiesen, um zu verhindern, dass die Animation ohne Zutun des Nutzers gestartet wird. Die Eigenschaft „fill“ bekommt den Wert „freeze“ zugewiesen, um zu erreichen, dass am Ende der Animation das animierte Bild beibehalten wird. Andernfalls würde zum Ausgangsbild der Animation zurückgekehrt werden.

Mit ein paar Zeilen JavaScript kann man nun jeweils eine der beiden „<animate>“-Eigenschaften ausführen.

document.getElementsByTagName("polygon")[0].addEventListener("click", function() {
  if (document.getElementsByTagName("polygon")[0].getAttribute("class") != "zehneck") {
    document.getElementsByTagName("polygon")[0].setAttribute("class", "zehneck");
    document.getElementsByTagName("animate")[0].beginElement();
  } else {
    document.getElementsByTagName("polygon")[0].setAttribute("class", "");
    document.getElementsByTagName("animate")[1].beginElement();
  }
}, false);

Im Beispiel wird dem Polygon per „addEventListener()“ eine Funktion zugewiesen, die per Klick auf das Element jeweils aufgerufen wird. Je nach zugewiesener Klasse des „<polygon>“-Elementes wird die erste oder zweite Animation ausgeführt – per Methode „beginElement()“.

Verwendet man JavaScript für die Steuerung von SVG-Grafiken, dürfen diese nicht per „<img>“-Element in einem HTML-Dokument eingebunden sein. Man sollte die SVG-Grafik entweder per „<embed>“-Element einbinden oder direkt ins HTML-Dokument implementieren.

Browser, die zwar das SVG-Format beherrschen, aber mit SVG-Animationen noch nichts anfangen können, werden nur die Ausgangsform der Animation darstellen.

(Artikelbild: Depositphotos)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.