SVG-Sprites
Ein Sprite ist eine einzige SVG-Datei mit einem Symbol pro Icon. Seiten referenzieren die Symbole mit <use>, der Browser lädt die Datei einmal herunter und speichert sie im Cache, und es läuft überhaupt kein JavaScript.
Das Sprite beziehen
Das Paket liefert unter glyphfox/sprite.svg ein Sprite mit allen Icons. Jedes Icon ist ein <symbol> mit der ID gf- plus Icon-Name, einer eigenen viewBox und den Stricheinstellungen des Sets.
npm install glyphfox cp node_modules/glyphfox/dist/sprite.svg public/icons/sprite.svg
<svg xmlns="http://www.w3.org/2000/svg"> <symbol id="gf-home" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">...</symbol> <symbol id="gf-search" viewBox="0 0 24 24" ...>...</symbol> ... </svg>
Alternativ können Sie die Datei von Ihrem Bundler kopieren und mit einem Fingerprint versehen lassen. In Vite liefert das Suffix ?url die endgültige URL des Assets:
import spriteUrl from 'glyphfox/sprite.svg?url'; export const icon = (name) => `<svg class="icon" width="24" height="24" aria-hidden="true"><use href="${spriteUrl}#gf-${name}"></use></svg>`;
Das vollständige Sprite enthält alle 419 Icons in 117,9 KB, mit gzip sind es 15,7 KB. Ein Sprite mit den 30 Icons, die eine typische App-Shell verwendet, ist 7,5 KB groß, mit gzip 1,3 KB; die CLI erstellt es für Sie, wie unten gezeigt.
Ein Symbol referenzieren
Schreiben Sie ein äußeres svg in der gewünschten Größe und ein use-Element, das auf das Symbol verweist. Das Symbol bringt seine eigene viewBox mit, daher braucht das äußere Element nur Breite und Höhe.
<button type="button" class="btn"> <svg class="icon" width="20" height="20" aria-hidden="true"> <use href="/icons/sprite.svg#gf-download"></use> </svg> Download </button>
.icon { width: 1.25em; height: 1.25em; flex-shrink: 0; vertical-align: -0.2em; } .btn:hover .icon { color: #ff7a1a; }
Die Symbole zeichnen mit stroke="currentColor", und color wird in den Inhalt von use vererbt. So folgt das Icon der Textfarbe seines Elternelements und jedem color, das Sie am äußeren svg setzen. Breite und Höhe in CSS überschreiben die Attribute, sodass die Größe der Schriftgröße folgen kann.
Nur vom selben Ursprung
Browser folgen einer use-Referenz nur zu einer Datei mit demselben Ursprung wie die Seite. Ein Sprite auf einem CDN wie jsDelivr oder auf einer anderen Subdomain Ihrer Website wird nicht dargestellt, und auch CORS-Header ändern daran nichts. Liefern Sie das Sprite von Ihrem eigenen Ursprung aus, oder rufen Sie es einmalig ab und fügen Sie es in die Seite ein:
// jsDelivr sends CORS headers, so fetch works where <use> across origins does not. const res = await fetch('https://cdn.jsdelivr.net/npm/glyphfox@1/dist/sprite.svg'); const holder = document.createElement('div'); holder.setAttribute('aria-hidden', 'true'); holder.style.cssText = 'position:absolute;width:0;height:0;overflow:hidden'; holder.innerHTML = await res.text(); document.body.prepend(holder); // now <use href="#gf-home"></use> works anywhere on the page
Das Sprite inline in die Seite einbetten
Ein Inline-Sprite besteht aus denselben Symbolen, die einmal direkt im HTML stehen, meist gleich nach <body>. Referenzen verwenden dann nur das Fragment #gf-home, es gibt keine zusätzliche Anfrage, und die Icons erscheinen schon beim ersten Paint. Der Preis dafür: Jede Seite enthält die Symbole erneut. Betten Sie daher lieber eine kleine Teilmenge ein als das vollständige Set.
<body> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" style="position:absolute;width:0;height:0;overflow:hidden"> <symbol id="gf-home" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">...</symbol> <symbol id="gf-search" viewBox="0 0 24 24" ...>...</symbol> </svg> <a href="/"><svg class="icon" aria-hidden="true"><use href="#gf-home"></use></svg> Home</a> </body>
Blenden Sie das Sprite über die Größe null und absolute Positionierung aus, nicht mit display:none. Manche Browser rendern keine Masken mehr, die sich in einem ausgeblendeten SVG befinden, und der Solid-Stil nutzt Masken, um seine inneren Linien auszusparen.
Eine Teilmenge mit der CLI erstellen
glyphfox build schreibt ein Sprite mit genau den Icons, die Sie auflisten, gerendert mit den Props, die Sie übergeben. Die Namen können von der Kommandozeile oder aus einer Datei mit einem Namen pro Zeile stammen; in der Datei sind Leerzeichen, Kommas und Kommentare mit # erlaubt.
npx glyphfox build home search settings bell user --type sprite --out public/icons npx glyphfox build --from icons.txt --type sprite --weight 1.5 --out public/icons npx glyphfox build --from icons.txt --type sprite --variant solid --out public/icons/solid
# app shell home, search, settings, bell, user menu x chevron-down # badges and fusions work too file+check cloud&lock:overlap
Einfache Namen behalten ihre ID: Aus home wird gf-home. Angaben mit einem Badge oder einer Fusion erhalten eine ID, in der die Sonderzeichen ersetzt sind: Aus file+check wird gf-file_check und aus cloud&lock:overlap wird gf-cloud__lock-overlap. Öffnen Sie die generierte Datei einmal, um die benötigten IDs zu kopieren.
Erstellen Sie das Sprite in der Größe, in der Sie es anzeigen, erhalten Sie zusätzlich die optische Kompensation der Komponenten: --size 16 schreibt den etwas kräftigeren Strich, den glyphfox für Icons mit 16 Pixeln verwendet. So wirkt ein Sprite für dichte Tabellen genauso kräftig wie der Rest der Oberfläche.
Derselbe Befehl mit --type css schreibt stattdessen ein Stylesheet mit Maskenklassen (<span class="gf gf-home">), für Websites, die Icon-Klassen ohne Tailwind CSS möchten. Der Leitfaden zu Tailwind CSS erklärt, wie sich Masken-Icons verhalten.
Build-Optionen
Ein Sprite ist statisch, deshalb werden die gemeinsamen Props zu Build-Flags. Das sind die Flags, die für ein Sprite relevant sind; jedes Flag hat dieselbe Bedeutung wie die gleichnamige Prop in der Props-Tabelle.
| Flag | Wirkung auf die Symbole |
|---|---|
--type sprite | schreibt sprite.svg (der Standardtyp); css und package sind die anderen Typen |
--out DIR | Ausgabeverzeichnis, standardmäßig das aktuelle Verzeichnis |
--from FILE | liest die Namen aus einer Datei |
--weight N | Strichstärke von 1 bis 3, in jedes Symbol geschrieben |
--size N | die angezeigte Größe in Pixeln, für die optische Strichkompensation unter 24 |
--corners sharp | spitze Linienverbindungen und eckige Linienenden |
--variant duotone, --variant solid | der Stil aller Symbole |
--color C, --secondary-color C | feste Farben statt currentColor |
--secondary-opacity N | Deckkraft der Duotone-Ebene oder der Solid-Füllung |
--rotate DEG, --flip-x, --flip-y | schreibt eine Drehung oder Spiegelung fest in die Symbole |
Was CSS ändern kann und was nicht
Was use zeichnet, ist eine Kopie des Symbols. CSS am äußeren svg oder am use-Element erreicht diese Kopie nur über Vererbung, deshalb funktioniert color. Bei Eigenschaften, die das Symbol selbst setzt, funktioniert das nicht: Jedes Symbol trägt stroke-width, stroke-linecap und stroke-linejoin als Attribute, und diese haben Vorrang vor jedem Wert, der von außen geerbt wird. stroke-width auf .icon zu setzen, bewirkt nichts.
Legen Sie Strichstärke, Ecken und Stil beim Erstellen des Sprites fest, und erstellen Sie zwei Sprites, wenn Sie zwei Strichstärken brauchen. Wenn Sie Strichstärke, eine zweite Farbe oder Bewegung pro Instanz steuern möchten, rendern Sie stattdessen Inline-SVG mit einer Komponente oder toSvg.
Animationen des ganzen Icons funktionieren trotzdem, weil sie auf das äußere Element wirken: .icon.spin { animation: spin 1s linear infinite } dreht ein Sprite-Icon wie jedes andere Element.
Barrierefreiheit
Ein Sprite-Icon ist ein äußeres svg, das Sie selbst schreiben, daher legen Sie auch seine Semantik selbst fest. Verbergen Sie dekorative Icons mit aria-hidden="true". Bei einem Icon, das für sich allein eine Bedeutung trägt, machen Sie das äußere Element zu einem Bild mit Namen:
<svg class="icon" role="img" aria-label="Payment failed"> <use href="/icons/sprite.svg#gf-circle-alert"></use> </svg>
Buttons, die nur aus einem Icon bestehen, brauchen die Beschriftung am Button selbst, wie im Leitfaden zur Barrierefreiheit beschrieben.
Caching
Ein externes Sprite ist eine einzige Anfrage, die sich alle Seiten teilen. Liefern Sie es mit einer langen Cache-Dauer und einem Fingerprint im Dateinamen aus, etwa sprite.3f9a1c.svg, damit ein neuer Build die URL ändert, statt darauf zu warten, dass Caches ablaufen. Bundler erledigen das für Sie, wenn Sie die Datei importieren. Jede einzelne Sprite-URL wird pro Seite nur einmal heruntergeladen, egal wie viele Icons darauf verweisen.
Stolperfallen
- Ein Sprite von einem anderen Ursprung
- Ein externes
use, das auf ein CDN oder eine andere Subdomain zeigt, rendert nur eine leere Fläche; der Browser meldet die blockierte Anfrage lediglich in der Konsole. Hosten Sie die Datei auf dem Ursprung der Seite, oder betten Sie sie inline ein. - Duotone-Ebenen im vollständigen Sprite
- Die 42 Icons mit einer handgezeichneten Duotone-Ebene behalten diese in
glyphfox/sprite.svg, als durchscheinende Füllung in der aktuellen Farbe. Wenn Sie reine Konturen möchten, erstellen Sie eine Teilmenge: Der Standardstiloutlinelässt die Ebene weg, und--variant duotonebehält sie bei. - Masken in ausgeblendeten oder externen Sprites
- Symbole im Solid-Stil verwenden eine
mask, um ihre inneren Linien auszusparen. Masken werden unter Umständen nicht gerendert, wenn das Sprite mitdisplay:noneausgeblendet ist, und die Unterstützung für Masken in einer externen Sprite-Datei unterscheidet sich je nach Browser. Testen Sie den Solid-Stil in Ihren Zielbrowsern, oder betten Sie dieses Sprite inline ein. - Lebendige Zustände in einem Sprite
- Presets wie
spinoderdrawsind auf eine Klasse am Wurzelelementsvgbegrenzt, die in einem Symbol nicht erhalten bleibt. Daher hat--animatein einem Sprite keine sichtbare Wirkung. Animieren Sie das äußere Element mit eigenem CSS, oder verwenden Sie Inline-SVG. - Kollidierende IDs
- Ein Inline-Sprite bringt IDs wie
gf-homein die Seite. Zwei Inline-Sprites mit demselben Icon oder ein eigenes Element mit derselben ID machen Referenzen mehrdeutig. Betten Sie pro Seite nur ein Sprite inline ein.
Häufige Fragen
Wann ist ein Sprite besser als Komponenten?
Auf serverseitig gerenderten oder statischen Websites ohne JavaScript-Framework und auf Seiten, die viele Icons wiederholen: Die Symbole werden einmal heruntergeladen, und jede Verwendung kostet nur wenige Byte Markup. Komponenten sind im Vorteil, wenn sich Icons mit dem Zustand ändern, morphen, animiert werden oder eine zweite Farbe brauchen, denn ein Sprite ist zur Build-Zeit festgelegt.
Kann ich das Sprite direkt auf jsDelivr referenzieren?
Nicht mit use, denn Browser blockieren externe Referenzen auf andere Ursprünge. Rufen Sie die Datei ab und fügen Sie sie wie oben gezeigt in die Seite ein, oder kopieren Sie sie auf Ihren eigenen Server.