Ich bin ein großer Verfechter von Icon-Schriftarten. Viele Seiten brauchen wirklich ein System für Icons, und Icon-Schriftarten bieten ein verdammt gutes System. Ich glaube jedoch, dass die Verwendung von Inline-SVG und dem <use>-Element zum Verweisen auf ein Icon ein überlegenes System ist, vorausgesetzt, Sie sind mit IE 9+ vertraut.
Zuerst behandeln wir, wie es funktioniert.
Eine gute Möglichkeit, Ihre Icons zu handhaben, ist ein Ordner voller .svg-Dateien.

Sie können gefärbt, ungefärbt, mehrere Formen, Größen, was auch immer sein.

Sie können Illustrator (oder was auch immer) sie speichern lassen, wie sie sind, mit all dem unnötigen Ballast, der mitgeliefert wird
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="100px" height="100px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<g>
<path d="M50.049,0.3c14.18,0.332,25.969,5.307,35.366,14.923S99.675,36.9,100,51.409c-0.195,11.445-3.415,21.494-9.658,30.146 - yadda yadda yadda"/>
</g>
</svg>
Kombinieren Sie die .svg-Dateien
Sie können das manuell tun, wenn Sie möchten. Ich habe es getan. Sie müssen die finale Datei nicht einmal ansehen. Nennen Sie sie einfach svg-defs.svg oder so etwas.
Es sollte einfach ein <svg>-Tag mit einem <defs>-Tag sein (was nur bedeutet, dass Sie Dinge definieren, die später verwendet werden sollen), und dann eine Reihe von <g> (Gruppen)-Tags. Jeder <g>-Tag hat eine eindeutige ID und umschließt alle Pfade und was auch immer für jedes Icon.
<svg>
<defs>
<g id="shape-icon-1">
<!-- all the paths and shapes and whatnot for this icon -->
<g>
<g id="shape-icon-2">
<!-- all the paths and shapes and whatnot for this icon -->
<g>
<!-- etc -->
</defs>
</svg>
Auch das können Sie von Hand machen, aber das ist natürlich etwas mühsam. Fabrice Weinberg hat ein Grunt-Plugin namens grunt-svgstore erstellt, das dies automatisiert.
Wenn Sie noch nie Grunt verwendet haben, können Sie das tun. Hier ist ein Screencast, der Ihnen den Einstieg erleichtert.
Sie können es installieren mit
npm install grunt-svgstore --save-dev
Stellen Sie sicher, dass die Aufgabe verfügbar ist mit
grunt.loadNpmTasks('grunt-svgstore');
Und dann in der Konfiguration
svgstore: {
options: {
prefix : 'shape-', // This will prefix each <g> ID
},
default : {
files: {
'dest/svg-defs.svg': ['svgs/*.svg'],
}
}
}
},
In der Ausgabedatei, svg-defs.svg, wird jedes Icon (welche Pfade und Dinge auch immer aus der Quell-.svg-Datei) in einem <g>-Tag mit einer eindeutigen, vorangestellten ID und dem Dateinamen (ohne .svg) verpackt. So etwa:
<g id="shape-codepen">
Injizieren Sie dieses SVG am Anfang des Dokuments
Fügen Sie es buchstäblich ein, so:
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
<?php include_once("processed/svg-defs.svg"); ?>
Oder wie auch immer Sie das tun wollen.
Es muss leider ganz oben stehen, da es einen Chrome-Bug gibt, bei dem dies nicht funktioniert, wenn es später definiert wird. Obwohl... es gibt noch mehr zu dieser Geschichte, denn während ich diese Worte schreibe, hat das Theme, das diese Seite verwendet, die Icons am Ende des Dokuments definiert und es funktioniert. Ughkgh verwirrend.
Verwenden Sie die Icons überall
Jetzt können Sie sie überall verwenden! Zum Beispiel:
<svg viewBox="0 0 100 100" class="icon shape-codepen">
<use xlink:href="#shape-codepen"></use>
</svg>
<symbol> verwendet, sodass Sie nicht einmal den viewBox verwenden müssen!Stellen Sie sicher, dass Sie diese Klassennamen auf dem SVG verwenden, um es zu dimensionieren.
/* Do whatever makes sense here.
Just know that the svg will be an
enormous 100% wide if you don't
reign in the width. */
.icon {
display: inline-block;
width: 25px;
height: 25px;
}
Juhu: Sie können sie (und ihre Teile) mit CSS gestalten
Einer der Gründe, warum wir Icon-Schriftarten liebten, ist die Möglichkeit, sie mit CSS zu gestalten. Diese Technik übertrifft das noch, denn wir tun alles, was wir dort konnten, und mehr, weil
- Wir können alle einzelnen Teile gestalten
- SVG hat noch mehr Dinge, die Sie steuern können, wie spezielle Filter und Striche
Das SVG ist (irgendwie) im DOM, also auch JavaScript. Hier sind einige Styling-Möglichkeiten und eine Demo, wie das alles funktioniert
Siehe den Pen EBHlD von Chris Coyier (@chriscoyier) auf CodePen.
Eine andere Möglichkeit: IcoMoon
IcoMoon, bekannt für die Erstellung von Icon-Schriftarten, leistet auch hervorragende Arbeit bei der Erstellung von SVG-Sprites. Nachdem Sie alle gewünschten Fonts ausgewählt haben, klicken Sie auf die SVG-Schaltfläche unten und Sie erhalten die Ausgabe, einschließlich einer Demo-Seite mit der Inline-SVG-Methode.

Browser-Unterstützung
Auf der Seite der Browserunterstützung sind die Gefahrenzonen IE 8 und darunter, Safari 5 und darunter, iOS 4.3 und darunter sowie Android 2.3 und darunter. Aber wenn Ihre Richtlinie lautet "die letzten beiden Hauptversionen" – dann haben Sie fast 100 % Unterstützung.
Denken Sie daran, dass Icons nur eine unterstützende Rolle spielen können, immer begleitet von einem Wort. Wenn das der Fall ist, ist die Unterstützung nicht so wichtig. Wenn es sich um eigenständige Icons handelt und deren Nichtanzeige die Website unbenutzbar machen würde, ist das eine große Sache.
Ich würde wahrscheinlich zu Icon-Schriftarten greifen, da die Unterstützung dort viel tiefer ist. Stellen Sie nur sicher, dass Sie es richtig machen.
Das wird noch viel besser werden
Idealerweise könnten wir das so machen
<svg viewBox="0 0 100 100" class="icon shape-codepen">
<use xlink:href="/images/svg-defs.svg#shape-codepen"></use>
</svg>
Das funktioniert in einigen Browsern, was bedeutet, dass Sie den Include am Anfang des Dokuments überspringen könnten. Dies bedeutet eine zusätzliche HTTP-Anfrage, aber das bedeutet, dass Sie Caching effizienter nutzen können (nicht das Dokument-Caching aufblähen). In Tests hat Jonathan Neal entdeckt, dass Sie das xmlns-Attribut für das <svg> benötigen, damit es funktioniert
<svg xmlns="http://www.w3.org/2000/svg">
Aber selbst dann gibt es keine Unterstützung in irgendeinem IE. Es sei denn, Sie möchten das gesamte <svg><use> durch ein <object> ersetzen, was funktioniert. Jonathan Neal hat dies wieder herausgefunden
/MSIE|Trident/.test(navigator.userAgent) && document.addEventListener('DOMContentLoaded', function () {
[].forEach.call(document.querySelectorAll('svg'), function (svg) {
var use = svg.querySelector('use');
if (use) {
var object = document.createElement('object');
object.data = use.getAttribute('xlink:href');
object.className = svg.getAttribute('class');
svg.parentNode.replaceChild(object, svg);
}
});
});
Seine Demo enthält jetzt auch eine Methode, die einen Ajax-Aufruf für den Inhalt macht und diesen injiziert, was die Füllungen in IE 9 ermöglicht. Nicht so effizient, aber eher wie ein Polyfill.
Ich stelle mir vor, dass <svg><use>, das direkt auf die .svg verweist, eines Tages der Weg sein wird. Oder vielleicht sogar <img>, das mit URL-Fragmentbezeichnern für SVG funktioniert.
Browser behandeln <use> wie den Shadow DOM

Derzeit können wir beispielsweise einen einzelnen <path> mit CSS ansprechen, wie
.targetting-a-path {
fill: red;
}
Aber das beeinflusst alle Instanzen dieses Pfades. Sie würden denken, Sie könnten tun
svg.shape-version-2 .targetting-a-path {
fill: red;
}
Aber das funktioniert nicht. Es überschreitet diese Shadow DOM-Grenze. Idealerweise würden Sie den "Hut"-Selektor verwenden, um diese zu durchbrechen
svg.shape-version-2 ^ .targetting-a-path {
fill: red;
}
Aber das wird noch nicht unterstützt und es ist nicht ganz klar, ob das genau so funktioniert oder nicht.
"Gegenüber" Icon-Schriftarten
Vektor-basiert: Unentschieden
Mit CSS gestalten: leichter Vorteil für SVG-Sprites (Zielen auf Teile, SVG-spezifische Stile wie Striche)
Seltsame Fehler: SVG scheint einfach zu funktionieren (wenn unterstützt). Icon-Schriftarten scheinen auf seltsame Weise zu versagen. Zum Beispiel ordnen Sie die Zeichen normalen Buchstaben zu, dann schlägt das Laden der Schriftart fehl und Sie erhalten zufällige Zeichen. Oder Sie ordnen sie dem "Private Use Area" zu und einige Browser entscheiden sich, sie in wirklich seltsame Zeichen wie Rosen umzuordnen, aber es ist schwer zu reproduzieren. Oder Sie möchten die @font-face-Dateien auf einem CDN hosten, aber das ist Cross-Origin und Firefox hasst das, also benötigen Sie Ihren Server, um die richtigen Cross-Origin-Header zu liefern, aber Ihre Nginx-Einrichtung erfasst das nicht richtig, SEUFZ. SVG gewinnt diesen Punkt.
Semantik: Keine große Sache, aber ich denke, ein <svg> ist für ein Bild sinnvoller als ein <span>.
Barrierefreiheit: Vielleicht kann mir jemand sagen? Können/sollten wir dem <svg> ein Titel-Attribut oder etwas geben? Oder ein <text>-Element darin, das wir visuell verstecken? Update: Das <title>-Element könnte das tun. Oder vielleicht das <desc>-Element, wie in dieser SVG-Zugänglichkeits-Spezifikation verwendet.
Benutzerfreundlichkeit: Werkzeuge wie Fontello und IcoMoon sind für einen Icon-Schriftarten-Workflow ziemlich gut, aber die Ordner voller SVGs, die Grunt für Sie zusammenquetscht, sind meiner Meinung nach noch einfacher.
Ian Feather hat einen Artikel darüber gepostet, warum sie sich auch von Icon-Schriftarten abgewandt haben, und ich stimme jedem einzelnen Punkt zu.
Das war meine Idee! Chris hat meine Glorie gestohlen :D
Ich habe von Ihnen gelernt, dass es
<use>gibt! Erinnern Sie sich https://css-tricks.de/svg-tabs-using-svg-shape-template/Ich habe Hunderte von Dingen von Ihnen gelernt. Danke, Chris!
Danke dafür.
Ich dachte, es lohnt sich hinzuzufügen, dass es anstelle des Zuordnens eines @font-face-Icons zu PUA oder normalen Buchstaben auch die Möglichkeit gibt, sie ähnlichen Unicode-Äquivalenten zuzuordnen.
Wenn zusammen verwendet, erhalten Sie eine recht vernünftige Browserunterstützung
http://unicode.johnholtripley.co.uk/combined/
Ich denke, eines der großen Dinge, das Leute zu Icon-Schriftarten zieht, ist die riesige Menge an Icon-Sets. Für Leute, die ihre eigenen Icons nicht entwerfen können, ist das sehr wichtig. Ich habe in letzter Zeit jedoch viele weitere großartige SVG-Icon-Sets bemerkt. Eine gute Zusammenfassung von SVG-Icons wäre cool, ähnlich wie die, die Sie für Schriftart-Icons gemacht haben.
Denken Sie nicht, dass sie so unterschiedlich sind. Es ist trivial einfach, eine Icon-Schriftart-Glyphe in eine SVG-Datei umzuwandeln.
1) Erstellen Sie ein neues Dokument in Illustrator (oder was auch immer)
2) Aktivieren Sie die Icon-Schriftart
3) Geben Sie das Zeichen ein
4) In Pfade umwandeln
5) Als .svg speichern
Ich werde eine Runde der besten derzeit verfügbaren SVG-Icon-Sets machen.
Interessanter Artikel. Ich mag Icon-Schriftarten, weil sie auf SVG basieren, was die Skalierbarkeit erheblich erleichtert.
Es gibt eine nette Möglichkeit, eigene benutzerdefinierte Icon-Schriftarten zu erstellen, indem Sie diesem Link folgen...
Ihre benutzerdefinierte Schriftart
...und laden/ziehen Sie Ihre benutzerdefinierten SVG-Icons/Schriftarten hoch.
Danke für den Link
Ich bevorzuge immer noch Icons, weil ich sie wie Text stylen kann und sie MIT dem Text, neben dem sie stehen, stylen kann (Farbe, Schatten, Zeilenhöhe). Das ist besonders nützlich für Hover-Effekte auf Schaltflächen und wenn der Kunde sie nach Belieben in der Größe ändern oder neu einfärben möchte, ist das ein Kinderspiel.
Zugegeben, es hängt wirklich vom Projekt ab und Sprites sind für manche Projekte besser geeignet als für andere.
Ich bin neu bei Grunt und erhalte beim Ausführen von Grunt die folgende Fehlermeldung.
Lade "svgstore.js" Aufgaben... FEHLER
Ich habe das gleiche Problem – ich bin sehr gespannt darauf, dieses Tool zu verwenden (genau das, was ich für ein aktuelles Projekt brauche), aber Grunt scheint mir einige Probleme zu bereiten. Schade.
Hallo Terence, ich habe damit herumgespielt und konnte es nicht zum Laufen bringen. Haben Sie Glück gehabt?
Kein Glück – ich habe eine neue Grunt-Einrichtung vorgenommen, um sie ohne andere laufende Prozesse und mit der neuesten Version von Grunt zu testen, und erhalte immer noch den gleichen Fehler.
Weiß jemand eine Umgehung dafür?
Entschuldigung, es gab ein Problem mit dem npm-Paket.
Es ist in Version 0.0.2 behoben.
Scheinen jetzt andere Fehler zu bekommen – beginnend bei
Versuchen Sie, npm auf die neueste Version zu aktualisieren.
Was sind die Auswirkungen der Verwendung eines IMG-Tags und des Ziels der .svg-Datei als src? z.B.
<img src="my-icon.svg">. Ich habe auf CodePen getestet, um zu überprüfen, ob dies funktioniert (zumindest in Chrome). Ist daran etwas grundsätzlich falsch?Daran ist überhaupt nichts falsch. Ich mache das ständig. Aber mit einem Icon-System möchten Sie das wahrscheinlich nicht für die Dutzende/Hunderte, die für jedes Icon benötigt werden. Das Ziel ist Geschwindigkeit und die Reduzierung von HTTP-Anfragen, indem nur eine (oder keine) Datei(en) vorhanden ist, die alle Glyphen zusammen enthält.
Das Hauptziel hier ist, dass Sie Ihre Icons mit CSS stylen können. Wenn Sie das
<img>-Tag verwenden, verlieren Sie diese Möglichkeit. Und das zweite Ziel – eine HTTP-Anfrage, sicher.Wie Sie erwähnen, ist das Inline-Einbetten der gesamten Sprite-Sheet bei jeder Anfrage suboptimal.
Was ist mit dem Einbetten in einem
<object>-Tag und der Verwendung von JS, um beim Laden der Seite die SVG-Elemente aus dem Kinddokument in das aktuelle Dokument zu kopieren, damit sie dann per<use>referenziert werden können?In der Praxis (nicht auf CodePen) ist es einfacher. Fügen Sie einfach alle Ihre Icons in eine SVG-Datei ein und verweisen Sie im use-Element auf den Dateinamen zusammen mit dem Fragment. Die SVG-Datei wird vom Browser wie jede andere Bildressource, die von mehreren Seiten verwendet wird, zwischengespeichert.
Aber das funktioniert nicht, wenn Ihre "SVG-Datei" tatsächlich ein Link zu einer CodePen-Seite und keine tatsächliche Datei ist. Und es funktioniert auch nicht (in den meisten Browsern mit Standard-Sicherheitseinstellungen), wenn die Datei, auf die Sie verweisen, nicht auf derselben Domain liegt wie die Datei mit dem
<use>-Element, das darauf verweist. "Domains, Protokolle und Ports müssen übereinstimmen", sagt die Fehlermeldung in meiner Chrome-Konsole aus dem Beispiel, das ich zu erstellen versucht habe.Tolle Technik. Weiß jemand, ob es eine Möglichkeit gibt, dieses 'SVG-Spriting' zu machen, wenn die SVGs als Hintergrundbild verwendet werden sollen (wahrscheinlich in Kombination mit background-size)?
Sie können denselben SVG-Sprite mit background-image verwenden, aber ohne Inline-Einbettung können Sie SVG nicht aus CSS stylen.
Robert hat leider Recht. Es gibt jedoch eine Umgehung, die ziemlich gut funktioniert. Sehen Sie sich Ian Feathers Artikel dazu an, es ist eine sehr gute Erklärung.
Ich mag es nicht, dass Sie trotz des Vorteils der Verwendung von SVG immer noch mit Pixeln arbeiten müssen, um die Icon-Dimensionen anzugeben. Ich habe vor ein paar Wochen mit SVG-Sprites experimentiert und eine interessante Lösung gefunden.
Ich habe es auf diesem Sprite-generierenden Paket getestet und es funktioniert ziemlich gut.
Nun, Sie müssen keine Pixel verwenden (obwohl CSS-Pixel immer im Hintergrund vorhanden sind). Sie können das umschließende Element in jeder CSS-Einheit (em, rem usw.) dimensionieren und dann das Element darin in Prozent dimensionieren.
Chris' Methode hat einen argumentierbaren Leistungsvorteil gegenüber Ihrem SVG-als-CSS-BG, da bei ihm die Pfaddaten sofort inline geladen werden, während bei Ihnen die SVG-Datei erst vom Browser angefordert wird, wenn CSS geladen und geparst wurde. Hintergrundbilder kommen im Allgemeinen zuletzt – was Sie vielleicht wollen, je nach Ihren Prioritäten.
Was sagt uns diese Denkweise, dass wir nicht einfach SVG für alle Bilder verwenden können?
Fotografien.
@Eric
Aber selbst Fotos und andere Rasterbilder können in SVG eingebettet werden, um einfache Neuskalierung zu ermöglichen.
Also... Was ist die Wahrscheinlichkeit, dass wir alle unsere Layouts in SVG machen und foreignObject für Inhalte verwenden.
Sehr unwahrscheinlich. Alles mit SVG zu positionieren, ist im Grunde dasselbe wie alles mit absoluten Werten zu positionieren. Und obwohl Sie automatisch skalierbare
foreignObject-Elemente einbetten können (wenn man die derzeitigen fehlerhaften Implementierungen ignoriert), können Sie nicht einfach (ohne Skripting) das restliche Layout entsprechend anpassen.Tolle Lektüre...
Im CodePen, das die gestylten SVG-Icons zeigt... sagt der Füllstoff für das YouTube-Icon Folgendes:
.shape-youtube {
fill: url(#gradient);
}
... Was ist url(#gradient)... Ich kann nicht finden, was "#gradient" definiert...
Vielen Dank,
Habe die Antwort auf meine Frage gefunden... es ist ein SVG, das ein Gradient ist... und es ist im HTML definiert...
Es wäre schön gewesen, diesen Gradienten im
<defs>-Block zusammen mit allen Formen zu definieren. Ich glaube, das sollte funktionieren, aber es tut es nicht. Daher habe ich es in dasselbe<svg>wie das<use>verschoben.Die Referenzierung von Fragment-Identifikatoren aus Ihrem CSS kann zu Problemen führen. Opera und FF benötigen den Pfad mit der Haupt-SVG-Datei – url(icons.svg#element), während Webkits und IE nur die ID des Elements benötigen – url(#element). Wir könnten es durch Code-Vorverarbeitung und dann bedingtes CSS-Laden zum Laufen bringen, aber es ist nicht so elegant.
Es kann in einigen Fällen erforderlich sein, den Namespace für xlink festzulegen, damit er funktioniert. Es sollte etwa so aussehen:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16">Diese xmlns können manchmal eine echte Qual sein.
Guter Punkt. Wenn Sie
xlink:hrefin einer eigenständigen SVG-Datei benötigen, müssen Sie den Namespace angeben. Wenn der SVG-Code in ein HTML 5-Dokument eingebettet ist, können Sie die Deklaration weglassen, sodass sie leicht zu vergessen ist.Gute Arbeit, Bro. Sie sind ein Meister. Ich bin ein Neuling und möchte mehr über CSS und auch SVG-Sprites lernen..
Das ist großartig! Das Hinzufügen des SVG zu HTML bedeutet im Grunde keine Zwischenspeicherung des SVG (was eine sehr große Datei sein kann, wenn Sie viele Icons benötigen); aber ich denke, es gibt eine einfache Lösung dafür
Wir können einen relativen Link zur SVG-Datei gefolgt von der ID verwenden. Ich habe eine Demo-Seite zum Testen erstellt. Es scheint überall perfekt zu funktionieren; aber wenn Sie es lokal versuchen, schlägt es in Chrome fehl, mit einer Fehlermeldung wie dieser:
Wenn es auf einem Server gehostet wird, funktioniert es auch in Chrome. Dieser Ansatz löst das Problem des Caching, indem das SVG in das HTML eingefügt wird, und macht das HTML auch viel übersichtlicher.
Ich habe den Sprite-Generator von IcoMoon heute nach dem Lesen dieses Artikels aktualisiert. Wenn Sie IcoMoon verwenden, um Ihren SVG-Sprite zu generieren (verwenden Sie die Schaltfläche SVG anstelle von Font), wird das SVG in das HTML eingefügt, da sonst die Demo lokal in Chrome nicht funktioniert, was verwirrend wäre. Ich hoffe also, eine Lösung für Chrome zu finden. Vielleicht ist es nur ein Bug?
Ja, das habe ich auch schon gesehen. Ich habe einfach eine lokale Domain erstellt, um es zu testen, und es funktioniert gut. Es ist nur die gleiche Art von Sache wie die Notwendigkeit einer echten Domain für Ajax-Tests.
Der eigentliche Nachteil, direkt von
<use>auf die .svg-Datei zu verlinken, ist, dass es in IE-irgendetwas fehlschlägt. Ich habe den Artikel mit einigen Dingen von Jonathan Neal aktualisiert, die zu funktionieren scheinen. Sehen Sie seine Demo: http://sandbox.thewikies.com/svg/Es lohnt sich zu erwähnen, dass Sie eine Ajax-Anfrage verwenden können, um eine Icon-Sprite-Datei zu laden, sodass sie vom Browser zwischengespeichert wird. Vanilla js oder JQuery
Clever! Verzögertes Laden UND Nutzung des Browser-Caches UND Stoppen des Document-Cache-Bloats.
Kennen Sie ein Beispiel dafür? Ich denke, ich verstehe das Beispiel und möchte es versuchen, aber ich kann die SVG-Sprite-Datei nicht mit PHP laden, das ist für mich keine Option. Danke.
Toller Artikel und Einblick – ich werde das bei meinem nächsten Projekt ausprobieren und wahrscheinlich einige in der Zwischenzeit aktualisieren.
Schauen Sie sich dann Iconmelon an ;) Es verwendet die gleiche Technik
Toller Beitrag. Aber ich habe bemerkt, dass SVGs auf Mobiltelefonen weniger reaktionsschnell sind, aufgrund hoher Renderzeiten. Was ist die optimale Lösung für die Einbindung von Icons auf Mobiltelefonen? Base64-Kodierung?
Es sieht nicht so aus, als könnten :hover-Stile verwendet werden, um die Füllfarbe zu ändern, egal ob das SVG-Element oder die Gruppe angesprochen wird. Vermisse ich etwas oder ist das nur irgendein Shadow DOM Event-Bubbling-Malarkey?
Sie können :hover und andere Pseudoklassen verwenden.
Sie können Stile verwenden, um das Symbol als Ganzes anzusprechen, aber nicht einzelne Komponenten darin; die Stile werden in jedem Fall angewendet, sofern geerbte Stile nicht durch spezifischere Stile überschrieben werden.
Sie können also die Standard-Füllfarbe und die Standard-Konturfarbe (und alle anderen Eigenschaften wie fill-opacity oder stroke-opacity) ändern, aber Teile des Symbols, die keine Standardwerte verwenden, werden nicht geändert. Sie können auch den Vorteil nutzen, dass Sie das Schlüsselwort
currentColorinnerhalb des SVG verwenden können, um den Wert der CSS-color-Eigenschaft zu übernehmen, die für dieses Element gilt, und so unterschiedlich gefärbte Bereiche erstellen können, die Sie aus dem CSS steuern können.Demo hier
Ah, ich verstehe. Ich habe versucht, eine Füllung zu überschreiben, die ich direkt auf die
<group>angewendet hatte, mit einer CSS-Regel, die auf die<svg>angewendet wurde. Das ist nicht gut.Man könnte dies verwenden, um Ihre SVG zu erstellen. http://glyphter.com/
In Bezug auf Barrierefreiheit sollten Sie
<title>verwenden, um den gleichen Effekt wiealtauf einem<img>zu erzielen.Die -Tags im Codeblock unter „Combine the .svg files“ sind nicht geschlossen.
Hallo Chris
Es gibt auch ein „Polyfill“-Plugin, das eine .png generiert.
http://svgmagic.bitlabs.nl/
Ich denke, das ist eine elegantere Lösung als das Einbetten des SVG in ein Objekt ;)
Bestens
Lucas Dechow
Das ist eine großartige Idee! Leider scheint es mit Inline-SVG nicht zu funktionieren. Wir müssen es forken und diese Funktionalität hinzufügen)
Für alle, die Probleme damit haben..
Stellen Sie sicher, dass Sie Version 0.0.2 von svgstore in Ihrer package.json angeben, um das Abhängigkeitsproblem zu umgehen (d. h. chalk / cheerio nicht definiert).
Wenn Sie dann das Problem haben, bei dem ich feststeckte (Task läuft ohne Fehler… aber keine Dateien werden erstellt…), dann verwenden Sie die Standardwerte in Ihrem gruntfile.js wie folgt..
Alle Beispiele, die ich gefunden habe, gehen direkt in
options{}undfiles{}, aber in meinem Fall musste ich sie indefault{}einschließen – das habe ich schließlich herausgefunden, indem ich mir die gruntfile.js innerhalb von node_modules/svgstore selbst angesehen habe.Ups. Oben im Code fehlt eine geschweifte Klammer. Verwenden Sie
Danke dafür, Chris. Anstelle von GruntJS hatte ich gute Erfahrungen mit gulp und dem
gulp-svgminPlugin.Sie können auch automatisch PNG-Fallback für ältere Browser mit dem
gulp-svg2pngPlugin generieren.Wenn Sie es wirklich schick mögen, könnten Sie auch 8-Bit-PNGs mit 8-Bit-Alpha-Kanälen generieren.
Ich bin ziemlich neu im Programmieren und bin mir nicht sicher, ob diese Methode im Opera-Browser funktioniert. Ich komme hierher, um CSS-Code von euch zu lernen. Macht weiter so, Jungs, einige eurer Taktiken helfen mir beim Aufbau meiner Website. Danke, Jungs
Das eigentliche Problem hier ist, dass man SVGs nicht als Pseudo-Elemente verwenden und stylen kann. Oft sind Symbole rein visuell und werden als :before und :after codiert. Mit SVGs müssen wir dies als Hintergrundbild machen und verlieren daher die Möglichkeit, mit CSS zu stylen.
Tatsächlich können Sie SVGs als Pseudo-Elemente verwenden, wie hier
Ich muss herumspielen, was möglich ist, wenn man SVGs als Pseudo-Elemente oder Hintergrundbilder verwendet (defs, Hover-Styling usw.). Wenn wir das gleiche Maß an Kontrolle wie bei Inline-SVGs erreichen können, dann ist das super!
Ich verstehe, dass Sie sie als Hintergrundbild verwenden können, aber wie gesagt, Sie verlieren die Möglichkeit, die SVG-Eigenschaften (insbesondere
fill) zu stylen.Hier gibt es viele interessante Informationen, vielen Dank, dass Sie diese Schritte mit uns geteilt haben!
Ich habe das selbst noch nie getestet, aber ich höre immer wieder, dass die Verwendung von SVG in einigen Browsern zu einer erheblichen Leistungseinbuße führen kann. Kann jemand das bestätigen? (oder verneinen).
Es hängt wirklich vom Bild ab und womit Sie es vergleichen. Einige Arten von Grafiken würden große PNG/JPEG-Dateien erfordern, können aber als SVG recht kompakt sein, was sowohl für den Download als auch für die Nutzung ein Vorteil ist. Es hängt auch davon ab, was Sie damit machen wollen. Firefox scheint insbesondere Schwierigkeiten zu haben, SVG-Bilder zu verschieben – selbst wenn Sie das Bild überhaupt nicht ändern, scheint der Browser jedes Mal das Layout neu zu berechnen. Dies ist ein Problem, wenn eine Reihe von SVG-Symbolen als herkömmliches Sprite-Sheet verwendet wird, das durch Hintergrundpositionseigenschaften gesteuert wird, und ein weiterer Grund, Inline-SVG mit
<use>-Elementen für SVG-Symbole zu verwenden.Ich stimme Amelia zu, es kommt darauf an, was Sie tun. SVG ist tendenziell langsamer als einfache Rasterbilder, aber in vielen Fällen kann es schneller sein im Vergleich zu einem 2x-Bild, das für Bildschirme mit hoher Pixeldichte auf 1x skaliert wird. Aus meiner Erfahrung habe ich ungefähr 4 große Projekte mit der in diesem Beitrag beschriebenen Technik gestartet und hatte damit nie Probleme. Christophe Schwyzer hat interessante Tests durchgeführt, die für Sie interessant sein könnten.
Meine neuesten Erkenntnisse – Iconizr http://github.com/jkphl/grunt-iconizr
Tolles Werkzeug für einen automatisierten, vollständigen SVG-Workflow – SVG-Sprites/ dataURI/ PNG-Fallback über JS-Loader
Noch besser als GruntIcon!
Für Barrierefreiheit liebe ich die Idee, Schrift-Icons mit Ligaturen zu verwenden, die für ganze Wörter definiert sind. Screenreader würden das Symbol als normales Wort lesen, und sogar Kopieren und Einfügen würde Ihnen die Textversion liefern. Es könnte ziemlich raffiniert sein für etwas wie eine einfache Kontaktkarte mit Telefon, E-Mail usw.
Natürlich ist die Unterstützung eine andere Sache.
Das ist großartig und cool zugleich. Aber da ich beschlossen habe, dies selbst auszuprobieren, habe ich die Zusammenführung manuell vorgenommen (weil ich es gerne tue und das Terminal sehr leicht durcheinander bringe) und dann die PHP-Anfrage nach dem Body-Tag gemacht, wie Chris oben. Die Bilder werden dort geladen, wo ich sie haben möchte, aber es gibt einen riesigen weißen Fleck am Anfang des Dokuments, wo die SVG-Datei hereingeholt wird. Mache ich etwas falsch oder fehlt mir irgendwo Code, damit die SVG-Datei nicht als riesiger weißer Fleck dargestellt wird?
Verbergen Sie Ihre Inline-SVG-Quelle, indem Sie CSS-Stile hinzufügen. Etwas wie style=”position: absolute; margin-left: -100%” auf dem SVG-Tag sollte gut funktionieren.
Eine Liste von SVG-Eigenschaften, die von CSS gesteuert werden können finden Sie hier. Nur für den Fall, dass jemand sie braucht.
Toller Artikel! Aber was ist mit Animationen mit der CSS-Übergangseigenschaft?
Übergänge funktionieren wie üblich.
Animationen funktionieren nicht browserübergreifend, daher müssten Sie wahrscheinlich JavaScript verwenden, um Ihre Symbole zu animieren.
Sie können keine CSS-Transformationen auf SVG in FF und IE anwenden, daher können Sie sie offensichtlich auch nicht animieren und überblenden.
Chris,
Bezüglich der Position der defs-Codes schrieben Sie
Warum ist es also unten bei CSS-Tricks?
Ich habe einen Pen als persönlichen Test erstellt. Ich dachte, ich poste ihn für den Fall, dass er für andere Leser hilfreich ist. Ich habe die Vektoren in Illustrator erstellt und die Formen gruppiert, die dieselben Farben haben sollten, dann habe ich die Gruppen benannt, die zu Klassennamen wurden. Es hat mir geholfen, dies grafisch zu tun, um zu verstehen, was ich zusammen gruppiert habe.
Das Gulp-Äquivalent von grunt-svgstore ist gulp-svg-sprites.
Ich habe einen Ordner voller SVG-Symbole in meinem
src-Ordner. Ich lasse sie durchgulp-svg-spritesmitdefs: truelaufen, um einesprite.svg-Datei in meinempublic-Ordner zu erstellen. Dann generiere ich das HTML aus einer Jade-Vorlage in meinemsrc-Ordner, die den SVG-Sprite ganz oben enthält.Hinweis: Es ist wirklich schwierig, Kommentare mit Code zu posten, ohne Fehler von Securi zu erhalten.
Es scheint, als könnten SVG-Symbole nicht mehr auf die gleiche Weise gecached werden wie Sprites oder andere referenzierte Ressourcen. Wenn ich zum Beispiel 100 verschiedene Webseiten habe, die alle denselben Satz von Symbolen verwenden, wie vermeide ich es, diese Symbole 100 Mal an den Browser zu senden?
Auch für eine einzelne Webseite, wenn ein Teil davon dynamisch erstellt wird, ruft der Browser jedes Mal, wenn die Seite geladen wird, dasselbe statische SVG ab.
Wenn Sie IE-Versionen nicht unterstützen müssen, können Sie
<use xlink:href="sprite.svg#icon>verwenden, und es wird wie alles andere gecached. Ansonsten ja, einige Seiten-Cache-Bläschen, aber sicherlich kein Showstopper, zumindest nicht für mich.Gibt es eine Möglichkeit, das SVG einzubinden, ohne die viewBox-Größe kennen zu müssen?
d. h.
anstelle von
(und dann die Symbolbreite/-höhe mit CSS stylen)
Da ich Symbole mit verschiedenen Canvas/ViewBox-Größen habe, wäre es praktisch/schneller, sie einzubinden, ohne die viewBox ausschreiben zu müssen.
Außerdem scheint es keine Möglichkeit zu geben, Unterelemente des SVG mit dieser Methode anzusprechen?
Wenn ich das SVG direkt einbette, kann ich nur einen Pfad ansprechen und dessen Füllung mit CSS ändern. Wenn ich die ‚use‘-Methode wie oben verwende, scheint es, dass ich nur das Elternelement ansprechen kann, nicht Unterelemente.
Fehlt mir etwas?
Ich bin wirklich daran interessiert, dass dies funktioniert…
Entschuldigung, ich habe den Teil über den Shadow-DOM gerade noch einmal gelesen, der meine Frage beantwortet hat.
Frustrierend, da diese Methode ansonsten großartig zu sein scheint. Muss die SVGs, die komplexe Funktionalität erfordern, wahrscheinlich direkt einbetten und diese Methode für einfachere Symbole verwenden.
Zunächst einmal vielen Dank für diesen erstaunlichen Artikel. Ich verwende seit einigen Jahren PNG-Sprites über Compass und freue mich, dass SVG endlich Fuß fasst.
Ich bin jedoch etwas besorgt – wenn zwei oder drei Symbole enthalten sind, gibt es keine Frage nach der Leistung, aber wenn Sie einen Sprite mit 20-30 SVG-Symbolen haben und sie alle als Markup in Ihr HTML einfügen… wird das keine erheblichen Leistungsprobleme verursachen?
Entschuldigung, das habe ich nicht bemerkt.
Danke
Vielen Dank, Chris! Das ist ein wirklich toller Artikel!!
Für diejenigen, die Illustrator zum Erstellen von SVGs verwenden – Wenn Sie Ihre SVGs auf separaten Ebenen erstellen, können Sie ein Skript in Illustrator installieren, das es Ihnen ermöglicht, die Ebenen als einzelne SVGs zu exportieren. Dies hat meinen Workflow erheblich beschleunigt. Ich habe dann meine SVGs auf Icomoon hochgeladen und den SVG-Sprite anstelle der Schriftart generiert.
Chris, ich stimme Ihnen vollkommen zu, wenn Sie sagen:
„Ich stelle mir vor, dass das direkte Verlinken auf die .svg eines Tages der richtige Weg sein wird.“
Das wäre absolut großartig und würde die Dinge etwas sauberer halten!
Der Artikel besagt, dass das Sprite-Sheet am Anfang des Dokuments, direkt nach dem Body-Tag, eingefügt werden muss, aber ich habe bemerkt, dass CSS-Tricks sie tatsächlich ganz unten im Body hat. Was ist es also?
Ich glaube, was hier passiert ist, war, dass eine frühere Version von Chrome ein Problem damit hatte. Sie mussten oben sein, sonst würden nachfolgende
<use>-Instanzen fehlschlagen. Ich erinnere mich, es bestätigt zu haben, aber jetzt kann ich es nicht mehr. Also ist es entweder behoben oder ich bin verrückt. Jedenfalls ist es meiner Meinung nach besser unten, weil es das Rendering wichtigerer Inhalte nicht verzögert (wahrscheinlich).Obwohl das externe Verlinken noch besser ist und ich bald darüber schreiben werde.
Danke für die Antwort.
Wie würden Sie es extern verlinken, die Möglichkeit, die SVGs zu stylen, UND IE zu unterstützen?
Ich glaube, ich vermisse etwas hier.
Gibt es eine offensichtliche Fallback-Lösung für diese Methode?
Wo Schrift-Icons auch versagen, ist, wenn die Font-Antialiasing im System ausgeschaltet ist. Manche Nutzer (wie ich) bevorzugen nicht-antialiased Fonts (für die Augen) und ich schalte auch das Rendern von Remote-Fonts in Browsern aus, da viele Webfonts schlecht für ein nicht-antialiased Szenario gestaltet sind (mein Favorit ist PT Sans, funktioniert in beiden Fällen einwandfrei).
In diesem Setup liefern manche Schrift-Icons die richtigen Icons nicht und zeigen Quadrate an. Dies könnte mit dem Browser-Rendering zusammenhängen (z. B. schafft es Chrome irgendwie, schriftbasierte Icons auf *einigen* Webseiten, wo Firefox meist überall versagt, immer noch korrekt anzuzeigen), aber trotzdem…
Chris, ich habe bemerkt, dass Sie sagten, Sie würden darüber schreiben, wie man SVG extern verlinken kann. Haben Sie eine Ahnung, wie bald Sie das besprechen werden? Ich bin wirklich daran interessiert, den richtigen Weg dafür zu erfahren. In Ihrem Beispiel betten Sie das SVG oben mit PHP ein. Was wäre die richtige Methode, wenn Sie nur HTML verwenden und PHP keine Option ist?
Ich sehe, dass Sie in Ihrem Artikel unten bereits beantwortet haben, wie Sie es tun können. Danke, dass Sie diese beiden Artikel zusammengeführt haben.
Genauer gesagt habe ich heute darüber geschrieben, wie man eine externe Quelle mit (Inline-)SVG verwendet: https://css-tricks.de/svg-use-external-source/
Falls jemand eine Gulp-Variante des Grunt-Plugins möchte, schaut euch das an: https://github.com/coma/gulp-svg-icons
Es ist der Hammer!
Ich plane, für ein neues Projekt von PNG-Sprites zu SVG-Sprites zu wechseln. Ich exportiere die Assets, ein paar einfache Symbole und ein Logo von Illustrator CC und stelle fest, dass die Dateigröße riesig ist und ich meine es ernst. Der gesamte PNG-Sprite ist kaum 8 KB. Derselbe SVG-Sprite ist 3,5 MB!!! Einzelne Symbole erreichen 4 KB, wenn sie als PNG exportiert werden, und 40-50 KB, wenn sie als SVG exportiert werden. Das ist Wahnsinn. Ich habe sogar versucht, die einfachste Form (ein einfaches Quadrat mit Farbfüllung) zu exportieren, und sie belegt 4 KB!
Ich gehe davon aus, dass ich etwas falsch mache, da ich diese Größen nicht für normal halte. Ich kann jedoch nicht herausfinden, was es ist. Die Exportoptionen scheinen normal und auf ein Minimum eingestellt zu sein.
Wie groß ist Ihre durchschnittliche Icon-Datei?
Weitere Recherchen zeigen ein unerwartetes Verhalten: Das Hauptzeichenbrett ist ca. 1200×5000 px. Darin befinden sich die Symbole. Wenn ich versuche, ein Symbol "in situ" zu exportieren (d.h. das Hauptzeichenbrett löschen > das Symbol mit dem Zeichenbrett-Werkzeug durch Doppelklick in sein eigenes Zeichenbrett einwickeln > dann das ausgewählte Zeichenbrett als SVG exportieren), ist das Ergebnis ein 3,5 MB Icon. Wenn ich das jedoch tue: Kopieren Sie das Icon irgendwo außerhalb des Hauptzeichenbretts > dann wickeln Sie das Icon mit dem Zeichenbrett-Werkzeug durch Doppelklick in sein eigenes Zeichenbrett ein > exportieren Sie dann das ausgewählte Zeichenbrett als SVG. Alles ist in Ordnung, das resultierende Icon ist <4KB.
Es ist ziemlich seltsam, da ich in beiden Fällen ein einzelnes 60x60px Zeichenbrett erhalte, sodass das exportierte Asset die gleiche Größe haben sollte. Es scheint, als würde Illustrator das ursprüngliche 1200×500 Zeichenbrett exportieren, auch wenn es nicht mehr existiert.
Auf jeden Fall habe ich diese Fragen ins Adobe-Forum verschoben. Ich werde Sie auf dem Laufenden halten, wenn ich mehr finde…
Ich hatte eine schreckliche Zeit mit Illustrator und SVG. Meistens ging es darum, ordentliche Exporteinstellungen zu erzielen. Wenn ich den Illustrator-Bearbeitungsmodus nicht beibehalte, ist die Grafik beim erneuten Öffnen der SVG völlig durcheinander. Wenn ich jedoch diese Einstellung beibehalte, erhalte ich eine größere Datei, die nicht durch svgo zur Optimierung läuft.
Nachdem ich meinen SVG-Sprite aus Illustrator exportiert hatte, öffnete ich die SVG mit Sublime Text und schnitt eine Menge unnötigen Ballast heraus. Meine SVG-Datei ging von etwa 70k auf etwa 40k. Eine Sache, die Sie möglicherweise tun müssen, um die SVG-Dateigröße zu reduzieren, ist die Reduzierung der Geometrie der Symbole. Dies kann eine Frage des Vereinens, Subtrahierens, Erstellens von Umrissen von Elementen sein. Manchmal kann auch die Verwendung des Vereinfachungspfadwerkzeugs helfen. (Offensichtlich müssen Sie vorsichtig sein, um die Treue Ihrer Symbole in diesem Prozess nicht zu zerstören.)
Ein schneller Weg, um zu wissen, ob Sie die Geometrie reduzieren, ist, zu Speichern > SVG > SVG-Code zu gehen und schnell zu überprüfen, ob Sie die Geometrie reduziert oder erhöht haben. Außerdem habe ich meine SVG auf eine andere wichtige Weise reduziert: In einigen Fällen gab es Instanzen von Base64-kodierten eingebetteten Bildern. Vielleicht kann mir jemand erklären, warum sie dort sind, aber ich habe sie entfernt und keine Konsequenzen davon bemerkt.
Was dieser Artikel nicht erwähnt, ist, dass Sie, wenn Sie die CSS-
fill-Eigenschaft verwenden möchten, um die Farbe der ausgegebenen Symbole zu steuern, alle Instanzen von Inline-fill="..."aus der kompilierten SVG-Datei entfernen müssen. Ich hatte viel Kopfzerbrechen, als ich versuchte,.icon-x { fill: red; }zu verwenden, ohne Erfolg, weil meine SVG-symbols Inline-Füllungen hatten, die meine CSS überschrieben. Hoffentlich finden das einige nützlich.Sind SVG-Fragment-Identifikatoren nicht gut unterstützt, selbst in den neuesten und besten mobilen Browsern (z. B. Android 4+, iOS 6+)? Ich sehe Probleme in beiden, wo die Elemente einfach nicht konsistent angezeigt werden; manchmal erscheinen sie und manchmal nicht.
Ich liebe diese Technik aber. Vorausgesetzt, ich kann herausfinden, was meine sporadischen fehlenden Symbolanzeigen verursacht, ist es eine ausgezeichnete Lösung. Danke fürs Teilen!
Ich bin auf einen interessanten Bug (?) gestoßen, bei dem, wenn Sie das SVG mithilfe von ‚defs‘ als Teil eines Links (z.B. eines Symbols) einbetten – das Symbol selbst kein Klick-Event in jQuery registriert, aber das Klicken auf den Text schon. Ich glaube, das liegt daran, dass SVG-Events nicht nach oben blubbern?
Wenn Sie das SVG direkt einbetten, löst der Link aus, unabhängig davon, ob Sie auf den Text oder das Symbol klicken.
Einen einfachen Testfall, den ich erstellt habe, finden Sie hier
http://codepen.io/greenchameleondesign/pen/tubJz
Interessanterweise scheint es auszulösen, wenn Sie $(‚.element‘).click(function(){ … }) verwenden und nicht $(document).on(‚click‘, ‚.element‘, function(){ … });
Nur für den Fall, dass jemand das gleiche Problem hat – es wurde als Chromium-Bug erfasst und sollte in einer zukünftigen Version behoben werden. In IE ist es aber immer noch kaputt, würde ich schätzen :/
https://code.google.com/p/chromium/issues/detail?id=382872
Ich habe mit dieser Technik experimentiert.
Ich habe festgestellt, dass „sowohl unter Chrome 35 als auch unter Firefox 29 gut funktioniert, aber NUR, wenn die verknüpfte Datei sich auf derselben Domäne befindet, andernfalls wird sie durch domänenübergreifende Richtlinien blockiert.
http://codepen.io/denilsonsa/pen/vdeLu
Hallo Chris, für mich funktioniert der php include_once Befehl einfach nicht.
Was kann ich tun?