Ein ziemlich gutes SVG-Icon System

Avatar of Chris Coyier
Chris Coyier am

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

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

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.

Anzeige der Shadow DOM-Grenze in den Chrome DevTools

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.

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

  1. Eine JavaScript-Lösung, wie das Abrufen des gesamten Sprites per Ajax und das Einfügen, oder ein Polyfill.
  2. 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.