Es gibt einen weiteren, neueren Artikel zu diesem Thema, der einige neuere Informationen behandelt.
Inline-SVG ist eine großartige Möglichkeit, SVG zu verwenden, unter anderem deshalb, weil die einzelnen Formen, aus denen die Grafik besteht, skript- und stilgesteuert werden können. Die Formen befinden sich direkt im DOM. Aber bedeutet das, dass wir diese Formen auf jeder Seite direkt im HTML definieren müssen? Nein, wir können <use> verwenden, um sie von anderswo zu referenzieren. Idealerweise ist dieses "Anderswo" eine externe Datei, da diese Datei vom Browser zwischengespeichert werden kann, Effizienz!
Hier ist, was ich meine
<!-- `<use>` shape defined ON THIS PAGE somewhere else -->
<svg viewBox="0 0 100 100">
<use xlink:href="#icon-1"></use>
</svg>
<!-- `<use>` shape defined in an EXTERNAL RESOURCE -->
<svg viewBox="0 0 100 100">
<use xlink:href="defs.svg#icon-1"></use>
</svg>
Also ja: externe Ressource = der Weg zum Ziel.
Aber die Methode mit der externen Ressource funktioniert in keiner Version (bis zu 11 getestet) von Internet Explorer. Selbst in den Versionen, die Inline-SVG unterstützen: 9, 10, 11.
Glücklicherweise hat Jon Neal eine clevere Lösung. Es ist ein kleines Skript namens SVG for Everybody. Die Idee ist folgende: Verwenden Sie einfach <use>, als ob es funktionieren würde, und das Skript kümmert sich darum in IE 9, 10, 11. Ein Polyfill, nur für dieses Szenario (es funktioniert nicht irgendwo anders, wo Inline-SVG-Nutzung nicht bereits unterstützt wird).
Es funktioniert so
- Wenn der Browser IE 9, 10 oder 11 ist (User-Agent-Sniffing, aber das ist hier der Sinn der Sache).
- Ajax für die referenzierte SVG-Datei
- Finde das benötigte Teil, basierend auf der referenzierten ID (z. B. #icon-1)
- Füge dieses in das
<svg>auf der Seite ein

Ich finde Inline-SVG verdammt nützlich und dieses (winzige) Skript bedeutet, dass Sie es auf verantwortungsvollere (cachable) Weise nutzen können.
Was genau ist der limitierende Faktor für IE? Die Verwendung von
<use>überhaupt oder die Verwendung von<use>mit einer externen Ressource?Nun, wenn ich es richtig verstanden habe, rendern IE10 und abwärts kein SVG, das mit DEFS definiert und mit USE aufgerufen wird
Beispiel: http://www.dblok.net/svgtest.html
Mit http://netrenderer.com/ sehe ich, dass nur IE11 die SVGs rendert
Und ich denke, dass IE11 das SVG mit DEFS/USE rendert, aber nur, wenn die Quell-SVG nicht extern ist (aber das lasse ich Chris bestätigen)
<use>mit einer externen Quelle funktioniert nicht in IE 9, 10, 11. Das ist der ganze Punkt des Artikels =)Toller Artikel, danke für das Teilen dieses Polyfills…
Ich habe versucht, dies bei anderen Gelegenheiten zum Laufen zu bringen und war erfolglos… weiß jemand von einer bekannten, gut funktionierenden Demo davon irgendwo im Web, die man herunterladen und damit spielen könnte…
Ich lerne am besten durch Reverse-Engineering von bekannten, gut funktionierenden Dateien…
Ich habe es zum Laufen gebracht… werde als nächstes den Polyfill versuchen…. nochmal danke für all diese Infos zu SVG…
Michael!
Ich verlinke eine funktionierende Demo im Artikel: https://css-tricks.de/examples/svg-for-everybody/
Hallo Chris, Gilles hier, wir haben uns auf der BTConf getroffen (der große Franzose). Habe ich dir schon gesagt, dass du genial bist? :)
Das ist die Idee, die ich am Montag hatte. Das ist es, was ich dir zu erzählen versucht habe.
Meine Idee ist es, deinen SVG-Code in eine JS-Datei zu packen, wo es ein JavaScript-String mit einem document.write ist.
Hier ist eine solche Datei mit zwei SVGs: http://www.dblok.net/svgtest.svg.js)
Und hier ist ein Pen, der diese Datei in JS integriert und dann zwei separate SVGs über einen USE-Tag aufruft http://codepen.io/gfra/pen/xzGIo
Kein JS-Ajax-Aufruf, keine mehreren HTTP-Anfragen und die JS-Datei wird nach dem ersten Besuch gecacht muah!
Meine SVG/JS-Datei ist etwas lausig, ich habe sie letzten Montag schnell in meinem Hotel gemacht, ich hatte NICHT das Internet, um mir bei der Erstellung einer gut formatierten Syntax zu helfen.
Ziemlich clever!
Du würdest nur ein Build-Tool verwenden, um diese JS-Datei zu erstellen, genau wie du es für die defs.svg-Datei tun würdest.
Meine einzige Sorge ist
document.write. Das wird generell als schlecht angesehen, glaube ich (oft als "böse" bezeichnet), obwohl ich mich nicht mehr genau erinnere, warum. Ich glaube, es hat mit der Leistung zu tun, da es das Parsen und Ausführen von Dingen stoppt.Ja, es ist ziemlich übel, wenn es um die Leistung geht (ich glaube, es baut das DOM neu auf, wie Satan selbst es tun würde, oder noch schlimmer), aber die Idee war einen Versuch wert!
FYI, ich habe diese Technik auch ausprobiert
Sie ist auch ziemlich übel, aber... sie funktioniert auch!
Oh, ich glaube, meine Tricks funktionieren immer noch nicht in IE…. Der Polyfill holt sich den eigentlichen SVG-Code der entsprechenden ID…
Mein Fehler!
Erlaubt der Opera-Browser Tags?
Guter Polyfill! Ich habe ein kleines Gulp-Plugin, gulp-svgstore, erstellt, das SVGs zu einem kombiniert, das könnte hier erwähnenswert sein. Ich habe es mit gulp-inject in den Body-Tag verwendet, aber jetzt auf externe Quellen umgestellt.
Ich habe gerade versucht, diese Technik anzuwenden und gesehen, dass ich alles genau richtig verwendet habe. Allerdings wurde nichts in Chrome angezeigt. Ich habe die Konsole überprüft und eine Fehlermeldung "Unsafe attempt to load URL" gefunden. Ich habe das schnell in CodeKit eingefügt und es hat perfekt funktioniert. Vielleicht wissen das alle schon, aber man kann bei dieser Technik auf Cross-Domain-Probleme stoßen, wenn man lokal entwickelt, wenn man nicht mit einem Server entwickelt. Ich hoffe, das hilft jemandem. Nochmals vielen Dank für diesen Beitrag, Chris, er kommt für mich super rechtzeitig.
Warum werden Seiten, die SVG oder Icon-Fonts verwenden, manchmal komplett schwarz in Firefox 29? Scrollt man mit der Maus, wird es teilweise wieder angezeigt. Ist das ein Firefox-Bug?
Warum ein "sogar"?
Hallo Chris,
Zunächst einmal danke für den Artikel. Ich habe eine Frage zur Verwendung des Tags. Ist es noch möglich, auf die Pfade des SVG zuzugreifen? Sagen wir, ich rufe ein SVG über den
<use>-Tag innerhalb eines Anker-Tags auf. Ist es möglich, so etwas wiea:hover svg { fill: purple; }zu sagen?Danke für deine großartige Arbeit!!!!
Aber immer noch keine HTML-Includes…
Ich habe ein Problem in IE9 festgestellt. Die Konsole schreibt: "Die zur Vervollständigung dieses Vorgangs erforderlichen Daten sind noch nicht verfügbar. Datei: svg4everybody.js, Zeile: 37, Spalte: 4". Irgendwelche Ideen?
Ich bin mir nicht sicher, ob das jemand gepostet hat. Aber hier ist es, in Grunt, um die manuellen Teile zu entfernen.
https://www.npmjs.org/package/grunt-svg-combine
Ich verstehe den Vorteil davon nicht, Chris. Warum ist es besser, die SVG-Formen aus einer externen Datei zu liefern, als die Formen am Anfang jeder Seite (zum Beispiel über einen PHP-Include) einzubinden, wie Sie in Ihrem vorherigen Artikel vorgeschlagen haben?
Schließlich sind SVG-Formen oft durch sehr kleine Textdateien beschrieben, und durch das Einbinden der Formen am Anfang der Seite sparen Sie 2 Serveranfragen (eine für die SVG-Datei, eine für das JS-Polyfill).
Wird Caching hier wirklich einen großen Unterschied machen?
Nehmen wir an, es gibt 15 KB Icons in einem HTML-Block am Anfang jedes Dokuments.
usw.
Wenn sie in einer externen Ressource liegen und gecacht werden
usw.
Je mehr Seiten die Leute besuchen und je größer die Icon-Größe ist, desto größer ist die Auswirkung.
Ja. Caching macht immer einen Unterschied, auch wenn man es in manchen Kontexten nicht bemerkt.
Aber weil es bei der ersten Anfrage Ihrer Seite eine zusätzliche HTTP-Anfrage hinzufügt, könnte das eine gute Frage sein. Die allererste Anfrage der Seite wird nicht sehr schnell sein, wenn sie Ihr CSS, Ihr JavaScript und Ihre JS-Bibliotheken (nicht immer auf CDNs gehostet) und eine weitere Datei für Ihre SVGs aufrufen muss und darauf warten muss, dass all das heruntergeladen wird, um die Seite zu rendern.
Ich habe kürzlich gelesen, dass Google zur Beschleunigung von Ladezeiten Webentwicklern rät, die Stile für die erste Hälfte der Seite direkt im HTML-Code zu definieren, damit die Seite rendern kann, bevor die gesamte CSS-Datei geladen ist. Das ist ein unglaublich seltsamer Rat, aber hey, es ist Google, was willst du dagegen tun?
Dieser Rat verblüfft mich immer noch. Auf jeden Fall möchten Sie mit dieser Idee vielleicht Ihre SVGs in Ihre Seite einfügen, aber ich glaube nicht, dass das eine gute Idee ist.
Danke Chris, das ist eine nützliche Erklärung.
In Bezug auf das "warum" ganz oben, ist es nicht tatsächlich das Ergebnis davon, dass es sich um ein ersetztes Element handelt – das vom Betriebssystem stammt? Die Tatsache, dass es ein selbstschließendes Tag ist, sollte eigentlich keine große Rolle spielen, oder?
Ist das schließende Tag etwas, das aus der Anforderung geboren wurde, dass es Inhalt enthalten muss? Vielleicht sollte das erwähnt werden, um Verwirrung über diese nicht standardisierte Markupsprache zu vermeiden.
Ansonsten sieht es großartig aus, ich freue mich auf bessere ShadowDOM-Unterstützung in der Zukunft.
Ich habe diese Methode total geliebt, als ich sie ausprobiert habe, und dachte bereits, dass dies die Zukunft für SVG-Icons ist – aber dann habe ich festgestellt, dass sie unter Android, selbst ab Version 4.2, nicht funktioniert, also ist sie absolut nutzlos. :(
Kein Funktionieren unter Android ist bedauerlich, wahr. IE8 ist mir egal, aber Android ist schon wichtig :P
Aus einem anderen Grund habe ich versucht, einen echten externen Pfad zu verwenden, um auf eine SVG-Datei zu verweisen.
Es ist ein bisschen seltsam…
Es scheint, dass dies funktioniert (genauso wie 127.0.0.1)
Während dies fehlschlägt (interne Netzwerk-IP)
Dateien von echten externen Quellen schlagen ebenfalls fehl. Wie
Oder habe ich etwas verpasst?
PS
Die Codeblock-Funktion zeigt meinen Code nicht an, deshalb habe ich das '>' '<' weggelassen
Siehe hier
Ich denke, das ist eine Einschränkung des Browsers, dass Cross-Domain-Dateien nicht geladen werden können, nur von derselben Domain. Das habe ich auch versucht (Chrome bei mir).
Ja, du hast Recht. Wusste nicht, dass das so gehandhabt wird.
Hätte es am Muster erkennen sollen…
Danke!
Etwas spät zur Party, aber während ich svg4everybody (das großartig ist) und das IE8-Fallback ausprobiert habe, habe ich festgestellt, dass es keine der Klassen von Ihrem
element auf dasüberträgt. Das bedeutet, wenn Sie das SVG gestylt haben, z. B. durch Float, wird dies nicht auf das IE8-Fallback angewendet.Ein schneller Fix, wenn Sie Selectivizr verwenden, ist
.my-svg-icon ~ img– es scheint, dass IE8 standardmäßig das öffnende und schließende " als einzelne Elemente behandelt, die er nicht versteht, was bedeutet, dass sie, dasuse-Tag und dasimgGeschwister sind.Arg Tippfehler – es überträgt keine der Klassen von Ihrem SVG-Element auf das generierte img-Tag.
Und standardmäßig behandelt IE8 das öffnende und schließende SVG-Tag als einzelne Elemente.
Was ist mit der Vorschau-Post-Option passiert!
Ich bekomme das einfach nicht zum Laufen.
Mit dem neuesten Chrome kann ich SVG 'verwenden', wenn die SVG-Datei in die Seite eingebunden ist, aber wenn ich diese Methode anwende, bricht alles zusammen. Nichts scheint dort angezeigt zu werden, wo das SVG sein sollte.
Ich habe den Code schon unzählige Male überprüft. Ich weiß nicht, was ich davon halten soll.
Jegliche Debugging-Tipps wären hilfreich.
Ein schönes neues SVG von Iconmoon funktioniert einwandfrei, aber wenn ich es durch SVGO laufen lasse, stirbt es.
Funktioniert scheinbar nicht in Cordova-Apps, ich musste SVG mit defs im Body inline einfügen. Ich vermute, das liegt am file://-Protokoll.
Das funktioniert nur, wenn ich das angebe
Wenn ich also grunt-svgstore verwende, um meinen Sprite zu generieren, musste ich hinzufügen
Ich bin mir nicht sicher, ob das als korrekte Vorgehensweise gilt?
Auch die
viewBox-Größe scheint zu funktionieren, wenn sie in der externen SVG-Datei platziert wird, also wenn sie (wie oben) im gruntfile ist, können wir das HTML ein wenig kürzen.