SVG `use` mit externem Verweis, Zweiter Versuch

Avatar of Chris Coyier
Chris Coyier am

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

SVG hat ein <use>-Element, das im Wesentlichen bedeutet: Finde den SVG-Teil mit dieser #Kennung, klone ihn und füge ihn hier ein. Es ist eine wesentliche Zutat für ein SVG-Icon-System. Es gibt ein paar Dinge zu wissen, die wir bisher nicht behandelt haben.

Zur Erinnerung, es sieht so aus

<!-- Reference IN THIS SAME DOCUMENT -->
<svg>
  <use xlink:href="#icon-1"></use>
</svg>

<!-- EXTERNAL reference -->
<svg>
  <use xlink:href="sprite.svg#icon-1"></use>
</svg>

Diese #icon-1 Kennung verweist wahrscheinlich auf ein Symbol in dieser Datei, wie…

<svg xmlns="http://www.w3.org/2000/svg">
  
  <symbol id="icon-1" viewBox="0 0 1024 1024">
    <title>Kinda like alt text</title>
    <path class="path-1" d="..."></path>
  </symbol>

  ...

</svg>

Der Vorteil einer externen Referenz ist, dass sie den Browser-Cache gut nutzt.

Außerdem ist sie einfach zu handhaben. Sie geben den korrekten Dateipfad zur Datei (dem „SVG-Sprite“) an und verweisen auf eine Kennung, und es funktioniert einfach. Sie können Ihren Server so einrichten, dass diese Datei mit allen korrekten Headern ausgeliefert wird, sodass der Browser sie wie jeden anderen zu cachenen Asset behält.

Das Problem war IE, aber es wird behoben.

Die meisten Browser, die Inline-SVG unterstützten, unterstützten dies, sodass es fast nutzbar war, mit der großen Ausnahme von IE. Aber sie haben dies nun in Microsoft Edge behoben. Edge hat noch keinen riesigen Marktanteil, aber es ist die Zukunft unter Windows, sodass wir dies schließlich ohne zusätzliche Arbeit nutzen können werden.

Aufgrund der mangelnden perfekten Unterstützung gibt es zwei wichtige Umgehungsmöglichkeiten.

  1. Fügen Sie das SVG-Sprite in alle HTML-Dokumente selbst ein. Funktioniert super. Ist tendenziell sehr schnell, bläht aber den Seiten-Cache. Und um die beste Unterstützung zu erhalten, müssen Sie es am Anfang des Dokuments einfügen, was zu einer leicht verzögerten Darstellung von wahrscheinlich wichtigerem Inhalt führt. Oder…
  2. Ajax für das Sprite. Das dann den Browser-Cache nutzen kann. Es kann jedoch schwierig sein, dies ohne ein wenig FONI (Flash of No Icons) zu tun.

Sobald wir externe Verweise direkt nutzen können, ist es nicht dasselbe

Dieses Konzept entzog sich mir und deshalb wollte ich diesen Artikel schreiben.

Ich dachte, die externe Referenz sei die ultimative Lösung, weil sie alles tun könne, was das Inline-SVG bei der Referenzierung von SVG im selben Dokument tun kann. Aber leider kann sie das nicht. SVG-Referenzen auf diese Weise haben ihr eigenes separates DOM. Es geht über die normale Shadow-DOM-Grenze hinaus, der alle <use> unterliegen.

durch das

<svg class="icon-1">
  <use xlink:href="#icon-1"></use>
</svg>

Sie könnten CSS (im selben Stylesheet wie für den Rest der Website) schreiben, um es einzufärben

/* This works.
  It will cascade this fill through the shapes,
  as long as there are no presentational fill 
  attributes on the shapes themselves. */
.icon-1 {
  fill: red;
}

Das kann man mit einem extern referenzierten <use> tatsächlich immer noch tun. Aber man kann einzelne Formen nicht mehr so stylen wie zuvor.

/* You could reach individual shapes 
   to style because they share the same DOM. 
   But this WON'T WORK with externally referenced SVG. */
.path-1 {
  fill: yellow;
}

/* This won't work either way,
   because it crosses a shadow DOM boundary */
.icon-1 /* ~shadow~ */ .path-1 {
  fill: yellow;
}

Man kommt überhaupt nicht an die internen Formen heran, wenn man extern referenziert. Zum Beispiel vom HTML-Dokument aus

<script>
  var shape = document.querySelectorAll(".path-1");
  console.log(shape);
  // [ ] (empty set)
</script>

Hier ist ein Gist, der den Punkt verdeutlicht.

Es ist immer noch ziemlich cool.

Die Tatsache, dass die Kaskadierung in einer einzelnen Farbe immer noch funktioniert, macht es ziemlich nützlich. Die meisten Icons sind tendenziell einfarbig. Und Sie können immer noch *unterschiedliche* Einzelfarben haben.

Seltsame Zukunfts-Sachen

Tab Atkins hat in seiner verrückten Vorausschau einige potenzielle Ideen dokumentiert, genannt SVG-Parameter

.foo {
  background-image: url("http://example.com/image.svg" param(--color var(--primary-color)));
}

Das ist ein CSS-Beispiel, aber vermutlich könnte Inline-SVG dies auch nutzen.