Test auf Unterstützung von SVG als img

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Die Browserunterstützung für SVG ist nicht ganz einfach ein Ja oder Nein. Zusätzlich zu einigen Eigenheiten, wie sich diese Unterstützung auswirkt, hängt es davon ab, wie das SVG verwendet wird. Eine gängige Methode ist direkt in einem Bild-Tag, wie <img src="bild.svg" alt="beschreibung">.

Wie kann man erkennen, ob ein Browser die Verwendung von SVG auf diese Weise unterstützt?

Es ist eine Sache, einfach nur zu wissen, welche Browser das tun. Die einzigen wirklichen Gefahrenzonen sind IE 8- und Android 2.3. Man könnte User-Agent-Erkennung verwenden, und obwohl ich dem nicht zu wertend gegenüberstehen möchte, ist es generell eine schlechte Idee.

Ich habe mir SVGeezy angesehen, ein Mini-JavaScript-Plugin speziell zur Unterstützung von Fallbacks für SVG-als-img. Natürlich muss es dafür eine Feature-Erkennung durchführen. Im Quellcode ist es eine einfache Einzeilerzeile

supportsSvg: function() {
  return document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
}

Ich hatte document.implementation.hasFeature noch nie zuvor gesehen, also habe ich mich ein wenig umgehört, da es für etwas, von dem ich noch nie gehört hatte, zu gut schien, um wahr zu sein. Die meiste Dokumentation da draußen ist ziemlich generisch und deutet auf eine großartige Browserunterstützung hin, was mich noch skeptischer macht.

Die Sache ist: es ist so gut wie nutzlos. Es gibt fast immer true für alles zurück. Außer, anscheinend, im Fall von SVG-als-img, wenn es richtig ist. Als Skeptiker habe ich einen Test erstellt, um zu sehen, ob das wirklich stimmt.

Das erste, was ich tat, war zu überprüfen, wie Modernizr es erkennt, als die Anlaufstelle für Feature-Erkennung. Wichtiger Hinweis hier: Der Standard-SVG-Test von Modernizr (Modernizr.svg) testet nicht die Unterstützung von SVG-als-img, sondern die Unterstützung von SVG als <object> oder <embed>. Seien Sie sich dessen bewusst, wenn Sie es für Fallbacks verwenden. Testen Sie das Richtige (sie haben Tests für alle Möglichkeiten, wie Sie SVG verwenden können).

Sie haben einen Test speziell für SVG-als-img, der so aussah

Modernizr.addAsyncTest(function () {
  var img = new Image();

  img.onerror = function () {
    addTest('svgasimg', false);
  };
  img.onload = function () {
    addTest('svgasimg', img.width == 1 && img.height == 1);
  };

  // 1px x 1px SVG; must be base64 or URI encoded for IE9... base64 is shorter
  img.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==';
});

Dies erstellt ein neues Bildelement, injiziert eine Data-URI eines 1x1 SVG-Bildes und wartet dann entweder darauf, dass es fehlschlägt oder korrekt geladen wird.

Offensichtlich anders als der hasFeature-Test, also habe ich einen Pen erstellt, der die Ergebnisse beider Methoden zeigte. Dann habe ich es in allen möglichen verschiedenen Browsern getestet. Eine Mischung aus denen, die bekanntermaßen SVG-als-img unterstützen, und denen, die es nicht tun. In allen Fällen waren die Ergebnisse identisch. Seltsam, aber ziemlich cool!

Der ursprüngliche Modernizr-Test ist das, was sie einen "asynchronen" Test nennen, was bedeutet, dass er auf Callback-Funktionen angewiesen ist, um eine Antwort zu geben. Modernizr bevorzugt im Allgemeinen "synchrone" Tests, bei denen, sobald der Test definiert ist, er die richtige Antwort hat.

So ist es nach Besprechungen mit dem Modernizr-Team der Standardtest für SVG-als-img. Es ist noch nicht in einer Veröffentlichung enthalten, daher müssten Sie es vorerst einfach ausführen.

Modernizr.addTest('svgasimg', document.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#Image', '1.1'));

Ich werde diesen Beitrag (und die Version, die wir auf CodePen ausführen) aktualisieren, sobald er herauskommt.

Danke an Patrick Kettner für die Überwachung der Aufnahme in Modernizr, Stu Cox für das Feedback und die Zustimmung zur Ersetzung seiner ursprünglichen Methode, Ben Howdle dafür, dass er von dem coolen hasFeature() wusste und es in SVGeezy verwendete, und Mike Taylor für die Überprüfung seiner Nützlichkeit.

Oh, und wenn Sie erkennen, dass der Browser SVG-als-img nicht unterstützt, möchten Sie wahrscheinlich die src für ein unterstütztes Bildformat austauschen. Wahrscheinlich das-gleiche-bild.png, entweder automatisch basierend auf einer Namenskonvention oder selektiv basierend auf einem data-* Attribut.

Seitennotiz bezüglich "http://"

Lassen Sie sich nicht von dem unsicheren "http://" im beteiligten Parameter-String erschrecken. Es wird kein HTTP-Request gemacht, und es schadet einer HTTPS-Website nicht. Tatsächlich schadet es Ihnen, wenn Sie es ändern. Jim Coffey schreibt

Wenn Sie stattdessen 'https' angeben, werden die meisten Browser damit umgehen, aber IE wird den Test fehlschlagen.