von Andy Pillip

SVGs im Web praktisch einsetzen

Ein Experiment zu flexiblen SV-Grafiken in HTML für Responsive Design

SVG ist das Format der Wahl, wenn man zukunfts­sichere (Web)Anwendungen mit Grafiken bestücken möchte, die auch auf hoch­auf­lösenden Bildschirmen super aussehen.

Welche HTML-Techniken gibt es, SV-Grafiken ins Web zu bringen und wie gut sind sie für den praktischen Einsatz geeignet? Wie verhalten Sie sich in unterschiedlichen (mobilen) Browsern?

Verwenden Sie SVG noch heute, die Zeit ist reif

Auf diesen Aufruf bin ich bei meinen Recherchen mehrmals gestoßen. Doch in unserem letzten Projekt mit Anspruch auf gnadenlos scharfe Grafiken auch auf HD-Bildschirmen (Apple nennt sie Retina) stellt sich die Realität anders dar.

Ich habe ein kleines HTML-Experiment aufgebaut, um mir das mal genauer anzuschauen. Auf Lösungen mit JavaScript gehe ich hier nicht ein. Weiter unten findet sich eine zusammenfassende Tabelle der Testergebnisse.

Prinzipielle Browser­unter­stützung

Ein Blick auf Can I use SVG bringt zunächst nichts überraschendes: Internet Explorer versteht das Format erst ab Version 9, die üblichen Verdächtigen hatten schon immer Unterstützung für SVG.

Erstaunlich ist allerdings, dass gerade Google, die das Format SVG und Performance extrem bewerben, in die frühen Android-Browser (bis einschließlich Android 2.3) keine Unterstützung eingebaut haben. Und der Marktanteil dieser Browser(versionen) ist noch enorm.

SVG in HTML einbetten: die verschiedenen Elemente

In Frage kommen (neben JavaScript-Lösungen) das object-, das (jetzt wieder erlaubte) embed-, das img- und das svg-Element, die ich im Experiment getestet habe.

object

Dieses Element ist am vielversprechendsten, weil es eine lange Geschichte hat und einen ordentlichen Fallback bietet: Wird das zu ladenende Format nicht unterstützt, lässt sich mit HTML strukturiert eine Alternative angeben.

<object type="text/svg+xml" data="test.svg" width="100" height="100">
<p>Hier lässt sich strukturiert eine Alternative beschreiben</p>
<p>Oder einfach nur das wenig hilfreiche: Ihr Browser unterstützt kein SVG</p>
</object>

Die strukturierte Alternative macht theoretisch das object-Element sogar für normale Bilder attraktiver als das img-Element.

embed

Eigentlich ist es gar kein HTML-Element, wurde aber mit HTML5 wieder erlaubt, nachdem es viel für das Einbinden von Flash verwendet wurde.

Der Unterschied zum object-Element ist, dass man eine URL zum Herunterladen des richtigen Plugins angeben kann — aber keine Alternative.

<embed type="image/svg+xml" src="test.svg" />

img

Das gute alte Element zum Einbinden von Grafiken. Es wird erst mal als inline-Element dargestellt, bleibt also im Textfluss.

<img src="test.svg" width="100" height="100" alt=""/>

svg

Dieses Element ist erst mit HTML 5 hinzu gekommen, und referenziert die SVG-Datei nicht, sondern erwartet deren Quellcode direkt im HTML. Dadurch sind auch die Grafikelemente der SVG direkt im DOM-Baum und man hat den Vorteil, dass man in JavaScript uneingeschränkt Zugriff auf die SVG-Elemente hat und diese beeinflussen kann.

<svg version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink">
    <g fill="#fff">

</svg>

background-image (CSS)

Man kann natürlich auch in CSS statt in HTML die SVG-Datei zuweisen. Der Haken dabei ist, dass man das HTML-Element nicht mehr ohne weiteres im Verhältnis wachsen lassen kann — es sei denn man bedient sich eines Platzhalterbildes, das das Verhältnis beim Vergrößern einhält. Und man braucht auf jeden Fall irgendwo Text als Fallback.

#svg {
  background: url("test.svg") no-repeat left top;
  background-size: 100% auto;
}

Flexible Bilder (responsive images)

Natürlich ist genau so Anspruch, dass sich die Grafiken im Verhältnis an die gewünschte Größe anpassen. Ich brauche nicht von HD-Bildschirmen sprechen, wenn sich meine Grafiken nicht anpassen können, um auch auf Smartphones passend dargestellt zu werden.

Dieses Stückchen CSS sorgt für diese Anpassung im Experiment:

object, svg, img {
  display: block;
  width: 100%;
  height: auto;
}

Skalierbares SVG

SV-Grafiken verändern sich aber gar nicht in der Größe, wenn nicht bestimmte Angaben im svg-Element in der Datei gemacht werden.

Es braucht alle Attribute preserveAspectRatio="xMinYMin meet" width="100" height="100" viewbox="0 0 100 100", damit alle Browser damit umgehen können.

Verlinkte Vektor­grafiken

Vektorgrafiken machen besonders für Symbole, zum Beispiel auf Symbolleisten, Sinn. Genau dort ist ihre Aufgabe aber, zur Interaktion zu motivieren.

Also müssen die Grafiken auch verlinkbar sein, also in ein a-Element gepackt werden können. Zur besseren Darstellung habe ich im Experiment diesem Element einen schwarzen Rahmen gegeben.

Testgeräte und -browser

Für meinen kleinen Test hier hatte ich zur Verfügung:

  • iPad 3 mit Safari, Chrome 21 und Dolphin
  • Samsung Galaxy Tab mit Android 2.2.1, Firefox 17 und Opera mobile 12.10
  • Samsung Galaxy S3 mit Android 4.1.1, Firefox 17, Opera mobile 12.10 und Chrome 18.0
  • Ubuntu 12.04 mit Firefox 17, Chromium 20.0, Opera 12.11

Die Testseite

Auf meiner Testseite hat der body nicht die volle Breite, um die Skalierbarkeit erfassbar zu machen. Die Links haben einen schwarzen Rahmen, damit man sie erkennt.

die Testseite gibt die Browserkennung mit aus, z.B. Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0

Und zuerst gebe ich den User-Agent Inhalt aus, um die Browserversion dokumentieren zu können.

Test­ergebnisse

Browser und Plattformobjectimgsvgbackground-image mit platzhalterbild
Webkit
    
Chromium 20/Ubuntu 12.04falsche Größe, nicht verlinkbarokfalsche Größeok
Chrome 18/Android 4.4.1bisserl abgeschnitten, nicht verlinkbarokhorizontal Leerraumok
Chrome 21/iPad 3abgeschnitten, nicht verlinkbarzu breitnicht unterstütztok
Safari/iPad 3abgeschnitten, nicht verlinkbarzu breitnicht unterstütztok
Android Browser 2.2.1SVG wird nicht unterstütztSVG wird nicht unterstütztSVG wird nicht unterstütztSVG wird nicht unterstützt
Android Browser 4.4.1abgeschnitten, nicht verlinkbarzu hochnicht unterstütztok
Gecko    
Firefox 17/Android 2.2.1nicht verlinkbarokokok
Firefox 17/Android 4.4.1nicht verlinkbarokokok
Firefox 17/Ubuntu 12.04nicht verlinkbarokokok
Firefox 10 ESR/Windows 7nicht verlinkbarokokok
Presto    
Opera mobile 12.10/Android 2.2.1unscharf, nicht verlinkbarunscharfunscharfunscharf
Opera mobile 12.10/Android 4.4.1unscharf, nicht verlinkbarunscharfunscharfunscharf
Opera 12.11/Ubuntu 12.04nicht verlinkbarokokunscharf
Dolphin Browser/iPad 3abgeschnitten, nicht verlinkbarzu breitnicht unterstütztok
Trident    
IE 8/Windows 7nicht unterstütztnicht unterstütztnicht unterstütztnicht unterstützt
IE 9/Windows 7okokfalsche Größefalsche Größe
IE 10/Windows 8okokfalsche Größefalsche Größe

Fehlerhafte Skalierung

Völlig verwirrt war ich von einigen Browsern, zunächst im Safari auf dem iPad 3, die mir zwar die eigentliche Grafik in der richtigen Größe angezeigt haben, aber wahnsinnig viel Platz um die Grafik herum reserviert haben — und zwar immer unterschiedlich viel Platz. Mit wahnsinnig viel meine ich 3-Minuten-nach-unten-scroll viel.

Die Analyse der SVG-Datei hat mir dann gezeigt, dass die Angabe von width und height unbedingt nötig ist, damit die Grafik ordentlich skaliert. Andere Browser (Chromium) brauchen unbedingt die viewBox und das preserveAspectRatio.

Also müssen in der SVG-Datei unbedingt alle drei Angaben vorhanden sein. Nur Firefox und Opera können auch ohne richtig skalieren.

Verlinkbarkeit

Wichtig war, dass sich die SV-Grafik verlinken lässt. Dabei kann nur der Internet Explorer das object-Element verlinken.

img zu verlinken funktioniert bei allen Browsern ohne Probleme.

Leerraum

Webkit-Browser (Chromium, Chrome und Safari) präsentieren die Grafik im SVG-Element mit ordentlich Freiraum in der Vertikalen. Im object-Element existiert dieser Platz auch, aber das Element an sich hat die angegebene Größe.

Letzteres führt dazu, dass bei preserveAspectRatio="XMidYMid" die eigentliche Grafik abgeschnitten präsentiert wird. Am Touchscreen lässt sie sich wieder in die Mitte ziehen.

Unscharfe SVGs

SV-Grafiken sehen theoretisch auf jedem Bildschirm — oder auf Kinoleinwand — so scharf aus, wie es die Hardware erlaubt. Es handelt sich ja um Vektoren, nicht um pixelgenaue Angaben.

Opera mobile bringt aber eine Überraschung: Egal mit welchem HTML-Element die Grafik eingebettet ist, der Browser macht eine Pixelgrafik daraus, was die Grafik unscharf aussehen lässt. Zoomt man näher hin, sieht das katastrophal aus.

In Opera am Desktop sieht die Grafik zumindest per CSS eingebunden scharf aus.

Chrome auf Android macht aus dem SVG im img-Element eine unscharfe Pixelgrafik — und per CSS eingebaut sieht sie sogar noch schlimmer als das im img aus. Am Chrome auf dem iPad ist alles scharf.