SVG mit PNG-Fallback
In diesem Beitrag erfahrt ihr wie ihr mit Modernizr einen PNG-Fallback für SVG-Grafiken im HTML- und CSS-Code herstellt.
Das Dateiformat SVG (Scalable Vector Graphic) ist die Zukunft der Grafikformate im Web. Sofern sich SVG gestalterisch anbietet, überzeugt das Vektor-Format mit brillanter Bildqualität auf allen Displaytechnologien (z. B. Retina/HiDPI), stufenloser Skalierbarkeit und verhältnismäßig geringer Dateigröße.
Leider wird SVG in älteren Browsern (< IE8) nicht unterstützt. Bis diese Browser an Relevanz verloren haben, muss also eine Übergangslösung her. Mit Hilfe von Modernizr lässt sich ohne Schwierigkeiten ein sehr wartungsfreundlicher PNG-Fallback herstellen.
Feature-Detection mit Modernizr
Das Script Modernizr gehört bereits seit längerer Zeit zum Standardrepartoir eines Webdesigners. Für den Fall, dass euch Modernizr nicht bekannt sein sollte möchte ich aber einen kurzen Überblick geben.
Modernizr ist ein JavaScript mit dessen Hilfe ihr herausfinden könnt, welche HTML- und CSS-Funktionen der Browser unterstützt. Wenn das Script in der Website eingebunden ist, schreibt es verschiedene CSS-Klassen in den html
-Tag der Seite. Das sieht dann (in Chrome 29) so aus:
<html class="js flexbox canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths -webkit-">
Anhand dieser Klassen könnt ihr nun erkennen, welche Funktionen vorhanden sind und genutzt werden können. Achtet aber darauf Modernizr spätestens beim Projektabschluss noch einmal sauber zu konfigurieren. Beim Download kann festgelegt werden, welche Funktionen überhaupt überprüft werden sollen. Mit Blick auf die Performance der Website sollte man nur die Features überprüfen lassen, die auch eingesetzt werden.
SVG als CSS-Hintergrund
Kommen wir nun zum SVG-Fallback. Wir fangen mit der einfacheren Variante an: Eine SVG-Grafik die mittels CSS als background
zugewiesen wurde.
Wenn Modernizr aktiv ist und der Browser SVG unterstützt, ist die CSS-Klasse .svg
vorhanden. Wir schreiben im Code also zuerst die Fallback-Lösung mit einer PNG-Grafik als Hintergrund.
div {
height:300px;
width:300px;
background:url(img/background.png) 0 0 no-repeat;
}
Anschließend gehen wir nach dem Prinzip Progressive Enhancement vor und machen die SVG-Grafik von der entsprechenden CSS-Klasse abhängig.
.svg div {
background:url(img/background.svg) 0 0 no-repeat;
}
Das war schon alles. Wenn der Browser SVG unterstützt wird die SVG-Grafik als Hintergrund geladen, anderenfalls fehlt die Klasse .svg
und der Browser nutzt die PNG-Grafik als Fallback.
SVG als <img>-Tag im HTML-Markup
Bei SVG-Grafiken im HTML-Markup wird es etwas kniffliger, denn mit Hilfe der CSS-Klasse können wir hier keine Grafiken austauschen. Die Ausgangssituation sieht so aus:
<img src="img/image.svg" alt="SVG Grafik">
Mit ein wenig JavaScript (jQuery) kann bei aktivem Modernizr geprüft werden ob SVG vom Browser unterstützt wird.
if(Modernizr.svg) {
/* Tu etwas, wenn der Browser SVG versteht */
}
Wenn ihr eine Lösung anbieten möchtet, sofern der Browser keine SVGs unterstützt, dreht ihr das Ganze einfach um:
if(!Modernizr.svg) {
/* Tu etwas, wenn der Browser kein SVG versteht */
}
Automatisierter Fallback
Um die Arbeit bei der Bereitstellung von Fallback-Grafiken möglichst gering zu halten, bietet es sich an das Snippet wie folgt zu erweitern.
if(!Modernizr.svg) {
$('img[src$="svg"]').attr('src', function() {
return $(this).attr('src').replace('.svg', '.png');
});
}
Nun wird die Dateiendung aller Bilder automatisch von *.svg auf *.png umgeschrieben, sofern der Browser kein SVG unterstützt. Super praktisch.
Bei der Erstellung von SVGs in Illustrator müsst ihr nun nur noch zusätzlich eine PNG-Grafik mit gleichem Dateinamen exportieren.
Live-Demo beider Lösungen
Ich habe eine Live-Demo erstellt, die sowohl die CSS- als auch die HTML-Lösung beinhaltet. In einem modernen Browser wie Chrome sieht das Beispiel so aus:
Im Internet Explorer 8 unter Windows 7 hingegen, werden die PNG-Grafiken geladen.
Ihr könnt die Demo hier anzeigen lassen, bzw. die Dateien herunterladen.
»SVG Magic« erstellt PNG-Fallbacks automatisch
Das jQuery-Plugin SVG-Magic prüft ebenfalls ob der Browser SVG versteht. Wenn nicht, sendet das Script die SVG-Grafik an einen Server, konvertiert die Datei in PNG und lädt die PNG-Grafik. Sofern man jQuery ohnehin bereits einsetzt und auch keine Bedenken bei möglichen Performance- oder Sicherheitsproblemen hat, sollte man das Script einmal ausprobieren.
Ach ja, eben habe ich gerade noch einen Deiner neueren Artikel gelesen, wo Du diesen Code empfiehlst:
// Prüfe ob SVGs dargestellt werden können
if(!document.createElement(’svg‘).getAttributeNS){
$(‚html‘).addClass(’no-svg‘);
// Schreibe im HTML-Markup die Dateiendung *.svg auf *.png um.
$(‚img[src$=“svg“]‘).attr(’src‘, function() {
return $(this).attr(’src‘).replace(‚.svg‘, ‚.png‘);
});
} else {
$(‚html‘).addClass(’svg‘);
}
Wäre das eventuell noch besser?
Dieses Snippet basiert auf jQuery aber nicht mehr auf Modernizr.
Hallo Jonas,
vielen lieben Dank für Deine Hilfe. Um es jetzt zusammenzufassen: Welches der drei Snippets würdest Du als das beste empfehlen? Ist es besser, ohne Modernizr oder ohe uery/js auszukommen?
Das lässt sich nicht pauschal beantworten. Es hängt vom jeweiligen Projekt ab und von den Technologien die dort zum Einsatz kommen. Wenn du es nicht entscheiden kannst bzw. willst wende dich bitte an deinen Theme-Entwickler.
Hallo Jonas!
Ich habe den Beitrag versucht zu verstehen, da ich gerne svg Bilder auf meiner Seite einsetzen möchte. Ich habe eine Frage: Ich hatte vorher noch nie von Modernizr gehört, habe jetzt aber von meinem Themehersteller erfahren, dass ein WP-Theme Modernizr verwendet. Heißt das, dass ich einfach z.B. in den Themeoptionen svg-Bilder für Logo, Footer etc hochladen kann(und gleichzeitig png-Versionen mit denselben Namen in die Mediathek hochlade) und dann in meiner Child Theme function.php Dein Snippet
if(!Modernizr.svg) {
$(‚img[src$=“svg“]‘).attr(’src‘, function() {
return $(this).attr(’src‘).replace(‚.svg‘, ‚.png‘);
});
}
einfüge und somit ein Fallback erstellt wäre? Oder ist es doch komplizierter? Und eine letzte Frage: Was ist der Unterschied zwischen Deinem Snippet und folgendem:
if (!Modernizr.svg) {
var imgs = document.getElementsByTagName(‚img‘);
var svgExtension = /.*\.svg$/
var l = imgs.length;
for(var i = 0; i < l; i++) {
if(imgs[i].src.match(svgExtension)) {
imgs[i].src = imgs[i].src.slice(0, -3) + 'png';
console.log(imgs[i].src);
}
}
}
Vielen Dank schon mal im Voraus!
Hallo Lea,
das von dir erwähnte Snippet ist JavaScript auf Basis von jQuery und kein PHP. Du kannst es also nicht in der
functions.php
einfügen, sondern es gehört in die Scripte deiner Seite – beispielsweise in den Footer oder in ausgelagerte Dateien. Wo es sich am besten anbietet musst du mit deinem Theme-Entwickler besprechen. Darüber hinaus ist die Funktionalität abhängig von Modernizr. Das zweite von dir gepostete Snippet erledigt die selbe Aufgabe wie das in diesem Beitrag gezeigte Snippet, allerdings scheint deine Variante etwas fehlertoleranter zu sein was die Benennung von Dateien angeht. Abgesehen davon basiert es nicht auf jQuery.Die Info über die dynamischen fallbacks waren sehr interessant. Ich hab den Artikel gerne als Info in meinen eigenen Artikel über SVGs eingefügt. Was mich noch interessiert hätte: wie gut sind die Server von SVG MAGIC verfügbar? Kann man das international in Kundenprojekten einsetzen? Gibt es vielleicht eine Variante, die man auf eigenen Servern einsetzen kann. Sonst würden wir lieber auf fest generierte Fallback Bilder setzen.
[…] http://caniuse.com/#feat=svg • Artikel auf blog.kulturbanause über SVG mit PNG Fallback: https://blog.kulturbanause.de/2013/09/svg-mit-png-fallback/ • drweb.de über Adobe snap.svg für SVG Animationen: […]
Eine gute Fallback Lösung bietet auch das jQuery Plugin SVGMagic.
http://www.joocom.de/blog/svgmagic-svg-fallback-jquery-plugin/
was spricht gegen ein simples einbetten per „object“ + fallback?
Leider kann Modernizr nicht wirklich testen ob SVG als Background tatsächlich unterstützt wird (siehe hier: https://github.com/Modernizr/Modernizr/issues/687).
In der 3er Version soll das wohl möglich werden.
Vielen Dank, sehr hilfreicher Artikel wenn man sich das erste Mal mit svg-Fallbacks beschäftigt :)
Hallo Jonas,
zum einen muss ich – mal wieder – mit Erstaunen zu Kenntnis nehmen, wie selbstverständlich (im Abschnitt „Automatisierter Fallback“) jQuery-Funktionen eingesetzt werden, ohne dass der Artikel auch den leisesten Hinweis auf den Einsatz von jQuery enthält (ja, ich weiß, jQuery ist das neue Javascript … ;)). #justsaying
Ferner möchte ich auf Tools hinweisen, die den Einsatz von SVG mit PNG-Fallback insbesondere dann vereinfachen, wenn man mehrere bis viele solche SVG-Grafiken einsetzen möchte, z.B. als Icons oder als (nebenbei: insgesamt geräterübergreifend kompatibleren) Ersatz für Icon-Fonts verwenden möchte:
– Da ist zum einen Scott Jehl’s grunticon (https://github.com/filamentgroup/grunticon), das auf Node.js aufsetzt und ein Verzeichnis mit SVG-Icons in einen CSS-Icon-Kit konvertiert. Es gibt eine Online-Version davon: http://www.grumpicon.com/
– Ferner gibt es iconizr (https://github.com/jkphl/iconizr) von meiner Wenigkeit, welches ein PHP-Kommandozeilenskript ist und sehr ähnlich wie grunticon arbeitet. Der Hauptunterschied ist, dass iconizr zusätzlich SVG- und PNG-Sprites erzeugt und neben CSS- auch Sass-Code produzieren kann. Auch hierzu gibt es eine Online-Version: http://iconizr.com
Setzt man auf seiner Website viele SVG-Grafiken ein, und integiert sich eines dieser Tools gut in den eigenen Workflow, dann kann man sich damit nicht nur eine Menge Handarbeit sparen, sondern eine hochkompatible Lösung erreichen, die keine Abhängikeiten mit sich bringt (d.h. selbst auf den Modernizr kann verzichtet werden).
Hallo Joschi, vielen Dank für deine sehr hilfreiche Ergänzung und die vielen Link-Tipps. Ich habe im Text den Hinweis auf jQuery nachgetragen. Du hast recht, das war nicht ganz sauber :)
Hallo Jonas!
Wage Aussage jetzt, ich müsste nochmal den Test raussuchen, aber ich glaube Inline-SVG werden in Modernizr mit Modernizr.inlinesvg getestet. Irgendwo hatte ich das Problem mal, das SVG als background unterstützt wird, aber nicht in .
Interessante Lösung. Ich hatte das vor kurzem noch mit conditional comments gebaut, was aber relativ umständlich war.
Wirklich interessant. Vielen Dank für diesen Artikel
Man kann ja auch à la Google der Auffassung sein, dass man IE8 nicht mehr unterstützen muss. So ganz ist das Thema aber nicht vom Tisch: Laut der Statistik „Anteil der verschiedenen Android-Versionen an allen Geräten mit Android OS im August/September 2013“ [1] haben noch ca. 31% der Android Geräte die Version 2.3.*, deren Android-Browser SVG nur bruchstückhaft unterstützt. In Zeiten responsiven Webdesigns sollte das Problemkind also eher Gingerbread heißen statt IE8.
[1] http://de.statista.com/statistik/daten/studie/180113/umfrage/anteil-der-verschiedenen-android-versionen-auf-geraeten-mit-android-os/
Habe das bis jetzt immer über eine .ie8 Klasse gelöst aber deine Variante ist sauberer. Danke :)