Ich habe schon lange SVG-Icon-Systeme befürwortet. Tue ich immer noch. Um nur einige Vorteile zu nennen: Vektorbasierte Icons sehen in einer Welt mit hoher Pixeldichte großartig aus, SVG bietet viel Designkontrolle und sie sind vorhersehbar und performant.
Ich habe auch oft ein SVG-Icon-System befürwortet, das auf <symbol>s (einem „SVG-Sprite“) und dem <use>-Element zum Platzieren basiert. Ich habe meine Meinung ein wenig geändert. Ich denke nicht, dass das wirklich ein schlechter Weg ist, aber es gibt sicherlich einen *einfacheren* (und vielleicht ein wenig *besseren*) Weg.
Füge die Icons einfach inline ein.
Das ist alles. Entschuldigung, wenn Sie auf etwas Ausgefalleneres gehofft haben.
So wie das
<button>
<svg class="icon icon-cart" viewBox="0 0 100 100" aria-hidden="true">
<!-- all your hot svg action, like: -->
<path d=" ... " />
</svg>
Add to Cart
</button>
Oder vielleicht praktischer, mit Ihrem bevorzugten Server-Side Include
<button>
<?php include("/icons/icon-cart.svg"); ?>
Add to Cart
</button>
Wie ich sagte
<?php include "icon.svg
<% render "icon.svg"
<Icon icon="icon"
{% include "icon.svg"Direkt in das Markup einzufügen ist ein ziemlich 👍 Icon-System.
— Chris Coyier (@chriscoyier) 31. Mai 2017
Vorteil #1: Kein Build-Prozess
Sie benötigen keine ausgefallenen Werkzeuge, damit dies funktioniert. Ihr Ordner mit SVG-Icons bleibt ein Ordner mit SVG-Icons. Sie werden sie wahrscheinlich optimieren wollen, aber das war's dann auch schon.
Vorteil #2: Keine Shadow DOM-Eigenheiten
Als <use>-Referenz eingefügte SVG-Icons haben eine Shadow DOM-Grenze.

Das kann leicht zu Verwirrung führen. Zum Beispiel
var playButton = document.querySelector("#play-button-shape");
playButton.addEventListener("click", function() {
alert("test");
});
Das wird nicht funktionieren. Sie würden den Pfad im <symbol> ansprechen, was nicht wirklich etwas tut, und der Klick-Handler geht irgendwie im Klonen verloren. Sie müssten einen Handler wie diesen an das übergeordnete <svg> anhängen, z. B. #play-button.
Ebenso ein CSS-Selektor wie
.button #play-button-shape {
}
wird nichts auswählen, da sich zwischen diesen beiden Dingen eine Shadow DOM-Grenze befindet.
Wenn Sie Inline-SVG einfach direkt einfügen, gibt es keine Shadow DOM-Grenze.
Vorteil #3: Nur die benötigten Icons
Bei einem <use>/<symbol>-System haben Sie dieses SVG-Sprite, das wahrscheinlich auf jeder Seite enthalten ist, unabhängig davon, ob es auf jeder Seite verwendet wird oder nicht. Wenn Sie Inline-SVG einfügen, sind die einzigen Icons auf der Seite diejenigen, die Sie tatsächlich verwenden.
Ich habe das als Vorteil aufgeführt, aber es könnte irgendwie in beide Richtungen gehen. Fairerweise ist es möglich, ein SVG-Sprite zu cachen (z. B. per Ajax abrufen und auf die Seite einfügen), was ziemlich effizient sein kann.
@Real_CSS_Tricks wie cache-freundlich ist SVG <use>? #SVG #CSS
— Samia Ruponti (@Snowbell1992) 7. Juni 2017
Das ist eine etwas knifflige Frage. <use> selbst hat nichts mit Caching zu tun, es geht darum, wo sich das SVG befindet, auf das <use> verweist. Wenn das Sprite per Ajax abgerufen wird, kann es gecacht werden. Wenn das Sprite bereits Teil des HTML ist, kann dieses HTML gecacht werden. Oder <use> kann auf eine externe Datei verweisen, und diese kann gecacht werden. Das ist ziemlich verlockend, aber…
Vorteil #4: Keine Bedenken hinsichtlich der Cross-Browser-Unterstützung
Kein IE oder Edge Browser kann das
<use xlink:href="/icons/sprite.svg#icon-cart" />
Das heißt, das Icon über einen relativen Dateipfad verknüpfen. Der einzige Weg, wie es in der Microsoft-Welt funktioniert, ist, auf eine ID zu einem SVG auf derselben Seite zu verweisen. Es gibt Workarounds dafür, wie das Abrufen des Sprites per Ajax und das Einfügen auf die Seite, oder Bibliotheken wie SVG for Everybody, die die Browserunterstützung erkennen und das benötigte SVG abrufen und bei Bedarf einfügen.
Kleiner potenzieller Nachteil: Aufblähung des HTML-Caches
Wenn Sie sich für die Sprite-Route entscheiden, ist es verlockend, das Sprite mit einem relativen Pfad zu verlinken, um das Caching zu nutzen. Aber Microsoft-Browser verhindern das, so dass Sie die Wahl haben zwischen
- Eine JavaScript-Lösung, wie das Abrufen des gesamten Sprites per Ajax und das Einfügen, oder ein Polyfill.
- Das Sprite serverseitig in das HTML einfügen.
Ich mache eher die Option #2, da Option #1 zu asynchron geladenen Icons führt und das sich ruckelig anfühlt. Aber bei Option #2 hat man einen „aufgeblähten“ HTML-Cache, was bedeutet, dass dieses Sprite auf jeder einzelnen HTML-Seite immer wieder gecacht wird, was nicht sehr effizient ist.
Dasselbe kann man auch für direktes Inline-SVG sagen.

Fazit und TLDR: Aufgrund der Einfachheit, der Vorteile und der nur geringen Nachteile gehe ich davon aus, dass das direkte Einfügen von SVG-Icons zum beliebtesten Weg für die Verwaltung eines SVG-Icon-Systems wird.
Ein (zu meiner Überraschung) Nachteil dieses Ansatzes, den wir bei der Darstellung unserer Seite mit React gefunden haben: Wenn Sie viele Icons auf Ihrer Seite haben, kann die zusätzliche Arbeit, die React mit dem Rendern aller einzelnen Elemente innerhalb eines Icons hat, die Ladezeit spürbar verlängern im Vergleich zu einem
<use>-Tag.Wenn Sie React (und/oder ähnliche Tools) verwenden, ist das direkte Einfügen im Grunde dasselbe wie das Einfügen eines großen
<symbol>-Blocks in Ihr HTML? Sie landen irgendwie nur mit einem Sprite, das sich in einem JS-Bundle befindet.Soll ich Icons in separate Bundles aufteilen? Gibt es dieses Problem schon lange genug, dass es einen richtigen Weg™ gibt, damit umzugehen? Ist es nicht genug Overhead, dass es ein Problem ist?
Ich bin mir nicht sicher, was React / JS-Frameworks damit zu tun haben, aber im Grunde sind die im Artikel beschriebenen Unterschiede unabhängig vom Framework relevant.
Der beste Ansatz für SVGs hat sich immer um Ihren Anwendungsfall gedreht. Es gibt keinen „richtigen Weg“, da verschiedene Ansätze ihre Vor- und Nachteile haben. Zum Beispiel muss ich auf der Website, an der ich gerade arbeite, die Pfade meiner SVG animieren können. Wenn ich einen extern referenzierten Ansatz wie ‚myfile.svg#foo‘ verwenden würde, könnte ich das Caching seitenübergreifend nutzen, aber meine Fähigkeit, die Pfade darin zu animieren, wäre eingeschränkt (Shadow DOM-Probleme).
Um Ihre Frage richtig zu beantworten, müssten Sie alle verschiedenen SVG-Ansätze bewerten und was Ihre Bedürfnisse sind.
Ich binde beim ersten Laden ein Sprite ein, parke es aber auch im localStorage und füge es von dort für nachfolgende Seiten mit Inline-Skripten ein. Keine spürbaren Ruckler.
Können Sie diese Technik näher erläutern?
+1 zur Frage von Russell Bishop.
Ich benutze schon seit einiger Zeit eine Pug/Jade-Mixin, um SVG zur Kompilierungszeit in meine HTML-Datei einzufügen. Ich muss sagen, dass es nicht so wartungsfreundlich ist, wie ich es gerne hätte, aber es ist leistungsstark und flexibel.
Sie müssen in der Mixin eine „case“-Anweisung mit einer Zeile für jedes Icon pflegen und Ihre SVG-Dateien in Pug konvertieren.
Hier ist ein kleines Beispiel
https://codepen.io/albpara/project/editor/DBaYKn/#
Super, super, super
Wenn Sie einen Button mit einem SVG-Icon erstellen, sollte das Bild ohnehin in einem
<button>enthalten sein, unabhängig davon, wie Sie es anzeigen.Kann man nicht ein „:after“ im Button als Icon machen, mit dem SVG als Hintergrund? Keine Funktionalität am SVG, aber :(
Wenn Sie keine SVG-Funktionalität wünschen, könnten Sie einen Klassiker machen und ein :after oder :before am Button verwenden und das SVG zum Hintergrund machen. Es wäre schön, wenn wir SVGs auf diese Weise noch gestalten und bearbeiten könnten, aber ja… :(
Das können Sie, aber ich würde argumentieren, dass das SVG – ob Sie es per Inline oder als Hintergrundbild anzeigen – ein eigenes Element sein sollte, das *innerhalb* des Button-Elements liegt.
Ähm, warum?
Ich betrachte es als Trennung von Stil und Funktionalität.
Gibt es gute Lösungen für das Angular2 basehref-Problem mit SVG use # href?
Ein Beispiel für einen aktuellen Standard ist ein kurzer HTML-Snippet (wie
<i>) mit einem Klassennamen (wie<i></i>).Wenn es nur um Browserunterstützung geht, kann ich 6 Monate oder ein Jahr warten, und es ist kein Problem mehr für ein bestimmtes System? (Ich habe viele, viele Hacks und Browserfehler auf diese Weise überstanden, funktioniert wie ein Zauber)
Wie wäre Ihr Codebase im IDE (ganz zu schweigen von Problemen mit der Dateigröße) mit buchstäblich Zehn- bis Tausenden von Zeilen Inline-SVG-Code in Ihren Vorlagen, JS-Dateien usw.? (vielleicht meinen Sie für einfache Websites?)
Wie einfach ist es, Änderungen an einem Icon zu pflegen, das inline ist, im Vergleich zu anderen Methoden? (z.B.
<i></i>)Wie ist Inline besser als nur zu verwenden?
Sie scheinen spezifische Ziele mit dieser Methode zu verfolgen, ohne sie zu nennen. Möchten Sie bestimmte Elemente des Icons mit CSS gestalten, was nur durch Inline-Einfügen möglich ist? Vielleicht deckt Ihre Zielsetzung einige andere spezifische Bedürfnisse ab, mit denen normale Bilder oder Hintergrundbilder nicht gut funktionieren? (abgesehen von Browserunterstützungsproblemen)
Ich behalte alle Icons in einer XML-Datei, die per simpleXML zu PHP-Variablen auf jeder Seite wird, wo ich die Variablen dann inline ausgebe. So kann ein Icon durch Text, einen Kommentar oder Leere ersetzt werden. Es ist wie in der Sowjetunion, nur mit Icons statt Menschen – und mit XML!
Ich bin noch nicht bereit, das zu beantworten, aber es klingt gut!
Ich stimme Chris vollkommen zu. Ich habe jahrelang das Symbol / Use Icon System verwendet und vor kurzem festgestellt, dass die gesamte Gulp-Aufgabe, die Trennung von Icons, die JavaScript-Abhängigkeit für IE und die Kompilierung nur für 4 Social-Icons auf der Seite ein massiver Overkill ist. Habe genau zu Ihrem neuen Ansatz gewechselt – alles inline. Danke für den Artikel.
Das ist kein Problem. Ich benutze SVG-Icons seit Jahren intensiv.
Benutzen Sie einfach
<img>-Tags, geben Sie das viewBox-Attribut in der SVG-Datei / im SVG-Tag an, um Browserkompatibilitätsprobleme zu vermeiden, und stellen Sie sicher, dass der korrekte medientyp in den HTTP-Antwortheadern ausgeliefert wird!Die beiden Nachteile dabei sind…
Aber wenn diese Dinge keine Rolle spielen, ja, das ist sogar noch einfacher.
Ich habe ein paar verschiedene Methoden für SVG-Icons ausprobiert und komme immer wieder zum
<img>-Tag zurück, wenn ich weiß, dass keine Skripting benötigt wird.Jedes Icon erfordert möglicherweise zunächst eine separate HTTP-Anfrage, aber das kann ein Vorteil sein, wenn das Icon global verwendet wird und der Browser die SVG-Bilddatei cacht.
Wären mehrere Anfragen kein Problem, wenn Ihr Server mit HTTP/2 konfiguriert ist?
Sie können das Erscheinungsbild eines SVG-Tags nicht ändern.
Die externe Ressource mit SVG wird von Edge 13 und neuer unterstützt (https://developer.microsoft.com/en-us/microsoft-edge/platform/changelog/desktop/10547/).
Es gibt ein weiteres Polyfill, das kein Browser-Sniffing verwendet: https://github.com/Keyamoon/svgxuse.
Das ist es, was ich in letzter Zeit verwendet habe, und es funktioniert für IE ziemlich gut. Es gibt eine leichte Verzögerung, bis die Icons erscheinen, aber das halte ich für akzeptabel.
Ich liebe svgxuse auch.
Ich habe diesen Ansatz in meinem aktuellen Projekt verwendet.
Die Wartbarkeit ist kein Problem, vorausgesetzt, Sie verwenden eine Art von Vorlagen – vorzugsweise serverseitig. (Ich bemitleide alle, die mit der schlechten Leistung von clientseitigen Vorlagen kämpfen. Während ich die Vorteile von Daten von einer API verstehe, die im Browser zu Markup gemacht werden... für wahrscheinlich 90% der Projekte ist es ein performance-fressender Fehler.)
Ich mache das in einer Hybrid-Mobile-App mit dem Rhodes-Framework. Es gibt einen Rails-ähnlichen Server in der App und ERB-Vorlagen (ich weiß… ich finde ERB auch schmerzhaft, aber es ist, was verfügbar ist). Die Icons werden von Illustrator mit Entity-Stilen gespeichert, sodass Sie sie leicht mit CSS überschreiben können. Ebenen sind semantisch benannt, sodass Sie semantische IDs erhalten. Ein einfacher Pre-Build-Workflow ändert
id=inclass=in den SVGs. Also kann ich jetzt Farben ändern, animieren, was auch immer mit semantischen CSS-Klassennamen.Die
.svg-Dateien werden in_whatever.svg.erbumbenannt und in einem Verzeichnis abgelegt, das für die Template-Engine zugänglich ist. Jedes Icon ist also ein ERB-Partial.Ja, mit manueller Bearbeitung (oder einem Workflow) kann ich Partials oder anderes ERB-Markup in die Icons einfügen. Das mache ich derzeit bei einem Icon, einem statischen kreisförmigen Fortschrittsbalken. (Statisch, da sich der Fortschritt beim Betrachten der Seite mit dem Icon nicht ändern würde.)
progress_percentwird als lokaler Wert an das Partial übergeben.Ich habe Pläne, Text innerhalb der SVGs zu internationalisieren (i18n). Jeder Satz wird auf einer Ebene platziert und die Ebene erhält einen aussagekräftigen Namen, der zum Nachschlagen der Übersetzung in einer Tabelle verwendet werden kann. Derselbe Pre-Build-Workflow kann verwendet werden, um den Inhalt speziell markierter
<text>-Elemente durch z. B.<%= t :t_submit_btn_lbl %>zu ersetzen (wobeitmein Übersetzungshilfsfunktionsname ist).Die Rendering-Zeit der Vorlage ist in dieser speziellen Umgebung kein Problem, da die Vorlagen zu Ruby kompiliert und dann der Ruby zur Build-Zeit zu Ruby-Bytecode kompiliert wird. Zur Laufzeit wird nur Ruby-Bytecode ausgeführt und sobald eine Datei geladen ist, bleibt sie geladen.
Ein weiterer Vorteil ist, dass
<use>vom Browser etwas mehr CPU benötigt als das direkte Zeichnen von FormenJa, ich mache das schon seit einiger Zeit. Bin ein großer Fan dieser Lösung.
Danke für die Bestätigung!
Ich bevorzuge immer noch das Inline-SVG-Sprite innerhalb des CSS, um es entweder explizit mit
<i class="[size] [color] [type] icon">[Fallback]</i>zu verwenden. Der einzige Nachteil im Vergleich zum Einfügen von SVG in das HTML ist, dass Sie eine zusätzliche Anweisung pro Farbe benötigen. Icons wiederverwenden zu können, ohne die Seitengröße zu erhöhen, ist definitiv ein Vorteil.Was uns davon abhält, Inline-Icons zu verwenden, ist, dass das von uns verwendete CMS sie nicht problemlos unterstützt. Wir bräuchten auch, dass unsere Benutzer/Kunden Icons eingeben, wenn sie CTA-Boxen usw. hinzufügen. Wir verwenden ein SVG-Sprite und einen einfachen Klassennamen, um Icons dort hinzuzufügen, wo sie gewünscht sind, mit
::beforeund::after-Elementen – erstellt mit der Technik https://www.liquidlight.co.uk/blog/article/creating-svg-sprites-using-gulp-and-sass/Ich bin mir nicht sicher, ob man das als beste Methode in Bezug auf die Leistung bezeichnen kann, aber nach vielen verschiedenen Ansätzen bin ich zu dem gelangt, was ich für meine bevorzugte Implementierung bei der Verwendung von React halte: Jedes Icon ist einfach als Inline innerhalb seiner eigenen Komponente definiert. Das macht die Verwendung und Aktualisierung von Icons wirklich einfach und beeinträchtigt keine SVG-Funktionalität. Außerdem macht es die Erweiterung der Funktionalität mit React sehr einfach (z. B. habe ich ein Dateiplatzhalter-Icon mit einem Textelement, das sich je nach Dateityp ändert und das ich einfach über eine Prop übergebe).
Ich verwende alle meine SVGs inline, wo ich sie von einem PHP-Funktionsaufruf brauche.
Aber was ist mit Clipping? Sie benötigen IDs für die ClipPath. Und wenn Sie ein SVG-Icon mehrmals platzieren, müssen Sie alle Clipping-IDs ändern. Kennen Sie einen besseren Weg?
Das ist im Grunde, wie ich vue-awesome implementiere :D
Kann das kein Problem sein, wenn Sie ein ziemlich komplexes SVG-Symbol haben, das oft auf einer Seite verwendet wird? Ich habe zum Beispiel eine Liste von Artikeln, die alle mit einem kleinen Icon vor dem Titel angezeigt werden, um den Artikel zu „kategorisieren“. Wenn ich die SVG-Bilder für jeden Artikel inline einfüge, wird meine HTML-Datei riesig. Ist es ein gültiges Problem, beim USE-System zu bleiben?
Das ist auch meine Hauptfrage. In meinem Fall würde sich meine Dateigröße durch das Einfügen aller Icons exponentiell erhöhen, es ist einfach kein für alle Fälle passender Ansatz.
Die Lösung, die Inline-SVG zu löst, ist die Kontrolle über die SVGs zu ermöglichen. Aber wenn Sie das nicht tun wollen, funktionieren SVGs als Hintergrundbilder oder als ::after/::before-Einfügungen usw. (jedes andere System) gut, oder sogar besser als Inline-SVG.
Zu behaupten, Inline-SVG sei die beste Methode, bedeutet, viele Anwendungsfälle zu ignorieren, bei denen es buchstäblich die schlechteste Methode ist.
Genau im letzten Monat habe ich angefangen, ein besseres Verständnis für die beste Art und Weise zu entwickeln, Icons und Bilder für meinen persönlichen Blog zu verwalten. Insbesondere habe ich gelernt, dass mit HTTP2 Dinge wie Image-Sprites nicht mehr notwendig sein werden.
Ich bin mir nicht sicher, ob sich das bewahrheiten wird. Wir brauchen mehr Daten und mehr Testfälle, denke ich. Ich habe definitiv widersprüchliche Meinungen gehört. Ich glaube nicht, dass es so einfach ist wie „wenn Sie HTTP/2 verwenden, niemals etwas verketten.“
Wir verwenden hauptsächlich einen zweistufigen Ansatz.
Gemeinsame Icon/Bilder SVG
Für Bilder, die auf den meisten Seiten, Menüs, Logos usw. verwendet werden, verwenden wir tendenziell eine Inline-Sprite-Datei. Ja, es hat einen kleinen Build-Prozess, aber einige Vorteile für uns: Wir können es verwenden, um sprachspezifischen zugänglichen Text aus unserem CMS hinzuzufügen, was bei einzelnen SVG-Dateien weniger einfach zu sein scheint?
Um diesen mehrsprachigen/zugänglichen Text auf andere Weise zu erreichen, könnte man mehrere SVG-Dateien verwenden, z. B.
svg-en.svg,svg-fr.svgfür mehrere Sprachen?Oder vielleicht eine
<switch>in der SVG-Datei verwenden, z. B.Aber die Verwendung von
<switch>scheint weniger einfach zu warten zu sein, als es im CMS zu belassen?Einzelne & Weniger verwendete SVG
Für einzelne und/oder seltener verwendete einzelne SVG-Bilder, vielleicht Illustrationen oder Ähnliches, laden wir sie möglicherweise über einen Include und fügen sie auf diese Weise inline ein. Wir würden in diesem Fall wahrscheinlich einen Sprachwechsel verwenden.
Hat jemand Gedanken oder Kommentare zu diesem Ansatz? Mir kommt auch in den Sinn, dass es möglich sein könnte, die SVG-Datei beim ersten Start einzufügen/inline zu machen, sie dann aber mit einem Service Worker zu speichern und zukünftig aus dem Cache abzurufen? Ob das Vorteile hat, bin ich mir nicht sicher.
Das ist der Ansatz, den wir in der Produktion verwenden. Es ist einfach zu gestalten und zu animieren.
Erwähnenswert ist, dass Gzip-Komprimierung Sie bei mehrfacher Verwendung desselben Icons auf einer Seite davor bewahrt, sich über die Dateigröße Gedanken machen zu müssen. Das nimmt einen der Vorteile von
Sieht cool aus :) aber ich brauche oft SVG als Hintergrundbild, was ist mit denen, macht man dafür vorerst ein Sprite?