SVG ist das beste Format für Icons auf einer Website, daran gibt es keinen Zweifel. Es ermöglicht Ihnen, scharfe Icons unabhängig von der Pixeldichte des Bildschirms zu haben, Sie können die Stile des SVG beim Hovern ändern und Sie können die Icons sogar mit CSS oder JavaScript animieren.
Es gibt viele Möglichkeiten, ein SVG auf einer Seite einzubinden, und jede Technik hat ihre eigenen Vor- und Nachteile. In den letzten Jahren habe ich eine Sass-Funktion verwendet, um meine Icons direkt in mein CSS zu importieren und zu vermeiden, meinen HTML-Markup zu verunreinigen.
Ich habe eine Sass-Liste mit allen Quellcodes meiner Icons. Jedes Icon wird dann mit einer Sass-Funktion in eine Daten-URI codiert und in einer benutzerdefinierten Eigenschaft auf der Wurzel der Seite gespeichert.
TL;DR
Was ich hier für Sie habe, ist eine Sass-Funktion, die direkt in Ihrem CSS eine SVG-Icon-Bibliothek erstellt.
Der SVG-Quellcode wird mit der Sass-Funktion kompiliert, die ihn in eine Daten-URI codiert und dann die Icons in CSS-Custom-Properties speichert. Sie können dann jedes Icon überall in Ihrem CSS verwenden, als wäre es ein externes Bild.
Dies ist ein Beispiel direkt aus dem Code meiner persönlichen Website
.c-filters__summary h2:after {
content: var(--svg-down-arrow);
position: relative;
top: 2px;
margin-left: auto;
animation: closeSummary .25s ease-out;
}
Demo
Sass-Struktur
/* All the icons source codes */
$svg-icons: (
burger: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0...'
);
/* Sass function to encode the icons */
@function svg($name) {
@return url('data:image/svg+xml, #{$encodedSVG} ');
}
/* Store each icon into a custom property */
:root {
@each $name, $code in $svg-icons {
--svg-#{$name}: #{svg($name)};
}
}
/* Append a burger icon in my button */
.menu::after {
content: var(--svg-burger);
}
Diese Technik hat sowohl Vor- als auch Nachteile, nehmen Sie diese also bitte zur Kenntnis, bevor Sie diese Lösung für Ihr Projekt implementieren.
Vorteile
- Es gibt keine HTTP-Anfragen für die SVG-Dateien.
- Alle Icons sind an einem Ort gespeichert.
- Wenn Sie ein Icon aktualisieren müssen, müssen Sie nicht jede HTML-Templates-Datei durchgehen.
- Die Icons werden zusammen mit Ihrem CSS gecacht.
- Sie können den Quellcode der Icons manuell bearbeiten.
- Es verunreinigt Ihr HTML nicht durch Hinzufügen von zusätzlichem Markup.
- Sie können die Farbe oder einen anderen Aspekt des Icons immer noch mit CSS ändern.
Nachteile
- Sie können einen bestimmten Teil des SVG nicht mit CSS animieren oder aktualisieren.
- Je mehr Icons Sie haben, desto schwerer wird Ihre kompilierte CSS-Datei.
Ich verwende diese Technik meistens für Icons und nicht für Logos oder Illustrationen. Ein codiertes SVG ist immer schwerer als seine Originaldatei, daher lade ich meine komplexen SVGs immer noch mit einer externen Datei entweder mit einem <img>-Tag oder in meinem CSS mit url(path/to/file.svg).
SVG in Data URI codieren
Ihr SVG als Daten-URIs zu codieren ist nichts Neues. Tatsächlich hat Chris Coyier vor über 10 Jahren einen Beitrag darüber geschrieben, um zu erklären, wie diese Technik verwendet wird und warum Sie sie verwenden sollten (oder auch nicht).
Es gibt zwei Möglichkeiten, ein SVG in Ihrem CSS mit einer Daten-URI zu verwenden.
- Als externes Bild (unter Verwendung von
background-image,border-image,list-style-image,…) - Als Inhalt eines Pseudo-Elements (z.B.
::beforeoder::after)
Hier ist ein einfaches Beispiel, das Ihnen zeigt, wie Sie diese beiden Methoden verwenden können.
Das Hauptproblem bei dieser speziellen Implementierung ist, dass Sie das SVG jedes Mal manuell konvertieren müssen, wenn Sie ein neues Icon benötigen, und es ist nicht wirklich angenehm, diese lange Zeichenkette von unlesbarem Code in Ihrem CSS zu haben.
Hier kommt Sass zur Rettung!
Verwendung einer Sass-Funktion
Durch die Verwendung von Sass können wir uns das Leben einfacher machen, indem wir den Quellcode unserer SVG direkt in unsere Codebasis kopieren und Sass sie ordnungsgemäß codieren lassen, um Browserfehler zu vermeiden.
Diese Lösung ist größtenteils von einer bestehenden Funktion inspiriert, die von Threespot Media entwickelt wurde und in ihrem Repository verfügbar ist.
Hier sind die vier Schritte dieser Technik:
- Erstellen Sie eine Variable mit allen Ihren SVG-Icons.
- Listen Sie alle Zeichen auf, die für eine Daten-URI übersprungen werden müssen.
- Implementieren Sie eine Funktion, um die SVGs in ein Daten-URI-Format zu codieren.
- Verwenden Sie Ihre Funktion in Ihrem Code.
1. Icon-Liste
/**
* Add all the icons of your project in this Sass list
*/
$svg-icons: (
burger: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24.8 18.92" width="24.8" height="18.92"><path d="M23.8,9.46H1m22.8,8.46H1M23.8,1H1" fill="none" stroke="#000" stroke-linecap="round" stroke-width="2"/></svg>'
);
2. Liste der maskierten Zeichen
/**
* Characters to escape from SVGs
* This list allows you to have inline CSS in your SVG code as well
*/
$fs-escape-chars: (
' ': '%20',
'\'': '%22',
'"': '%27',
'#': '%23',
'/': '%2F',
':': '%3A',
'(': '%28',
')': '%29',
'%': '%25',
'<': '%3C',
'>': '%3E',
'\\': '%5C',
'^': '%5E',
'{': '%7B',
'|': '%7C',
'}': '%7D',
);
3. Codierungsfunktion
/**
* You can call this function by using `svg(nameOfTheSVG)`
*/
@function svg($name) {
// Check if icon exists
@if not map-has-key($svg-icons, $name) {
@error 'icon “#{$name}” does not exists in $svg-icons map';
@return false;
}
// Get icon data
$icon-map: map-get($svg-icons, $name);
$escaped-string: '';
$unquote-icon: unquote($icon-map);
// Loop through each character in string
@for $i from 1 through str-length($unquote-icon) {
$char: str-slice($unquote-icon, $i, $i);
// Check if character is in symbol map
$char-lookup: map-get($fs-escape-chars, $char);
// If it is, use escaped version
@if $char-lookup != null {
$char: $char-lookup;
}
// Append character to escaped string
$escaped-string: $escaped-string + $char;
}
// Return inline SVG data
@return url('data:image/svg+xml, #{$escaped-string} ');
}
4. Ein SVG auf Ihrer Seite hinzufügen
button {
&::after {
/* Import inline SVG */
content: svg(burger);
}
}
Wenn Sie diese Schritte befolgt haben, sollte Sass Ihren Code ordnungsgemäß kompilieren und Folgendes ausgeben:
button::after {
content: url("data:image/svg+xml, %3Csvg%20xmlns=%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox=%270%200%2024.8%2018.92%27%20width=%2724.8%27%20height=%2718.92%27%3E%3Cpath%20d=%27M23.8,9.46H1m22.8,8.46H1M23.8,1H1%27%20fill=%27none%27%20stroke=%27%23000%27%20stroke-linecap=%27round%27%20stroke-width=%272%27%2F%3E%3C%2Fsvg%3E ");
}
Custom Properties
Die nun implementierte Sass svg()-Funktion funktioniert großartig. Aber ihr größter Nachteil ist, dass ein Icon, das an mehreren Stellen in Ihrem Code benötigt wird, dupliziert wird und Ihr kompilierter CSS-Datei erheblich schwerer werden könnte!
Um dies zu vermeiden, können wir alle unsere Icons in CSS-Variablen speichern und auf die Variable verweisen, anstatt jedes Mal die codierte URI auszugeben.
Wir behalten denselben Code wie zuvor bei, aber dieses Mal geben wir zuerst alle Icons aus der Sass-Liste in die Wurzel unserer Webseite aus.
/**
* Convert all icons into custom properties
* They will be available to any HTML tag since they are attached to the :root
*/
:root {
@each $name, $code in $svg-icons {
--svg-#{$name}: #{svg($name)};
}
}
Anstatt nun jedes Mal die svg()-Funktion aufzurufen, wenn wir ein Icon benötigen, müssen wir die Variable verwenden, die mit dem Präfix --svg erstellt wurde.
button::after {
/* Import inline SVG */
content: var(--svg-burger);
}
Optimierung Ihrer SVGs
Diese Technik bietet keine Optimierung für den Quellcode des von Ihnen verwendeten SVG. Stellen Sie sicher, dass Sie keinen unnötigen Code hinterlassen, sonst wird er ebenfalls codiert und erhöht die Größe Ihrer CSS-Datei.
Sie können diese großartige Liste mit Werkzeugen und Informationen zur richtigen Optimierung Ihres SVG überprüfen. Mein Lieblingstool ist Jake Archibalds SVGOMG – ziehen Sie einfach Ihre Datei dorthin und kopieren Sie den ausgegebenen Code.
Bonus: Icon beim Hovern ändern
Mit dieser Technik können wir keine bestimmten Teile des SVG mit CSS auswählen. Es gibt zum Beispiel keine Möglichkeit, die fill-Farbe des Icons zu ändern, wenn der Benutzer über den Button fährt. Aber es gibt ein paar Tricks, die wir mit CSS anwenden können, um das Aussehen unseres Icons trotzdem zu modifizieren.
Wenn Sie zum Beispiel ein schwarzes Icon haben und es beim Hovern weiß haben möchten, können Sie den CSS-Filter invert() verwenden. Wir können auch mit dem hue-rotate()-Filter spielen.
Bonus #2: Icon mit der CSS-Eigenschaft mask-image ändern
Ein weiterer Trick, um die Farbe Ihres Icons ändern zu können, ist die Verwendung als Maske auf Ihrem Pseudo-Element mit einem Hintergrund. Setzen Sie Ihr Pseudo-Element als inline-block mit einer background-color und definieren Sie eine width & height für die benötigte Größe.
Sobald Sie ein Rechteck mit der gewünschten Farbe haben, wenden Sie diese vier Werte an, um nur die Form des benötigten SVG beizubehalten:
mask-image: var(--svg-burger): Der Verweis auf unser Icon.mask-repeat: no-repeat: Um zu verhindern, dass die Maske dupliziert wird.mask-size: contain: Damit das Icon perfekt in das Rechteck passt.mask-position: center: Um unser Icon im Pseudo-Element zu zentrieren.
Vergessen Sie nicht, dass alle CSS mask-Eigenschaften im September 2022 noch mit -webkit- für die meisten Browser präfigiert werden müssen.
Danke an Christopher und Mike, dass Sie mich in den Kommentaren auf diesen Trick aufmerksam gemacht haben!
Das ist alles!
Ich hoffe, Sie finden diese kleine Helferfunktion in Ihren eigenen Projekten nützlich. Lassen Sie mich wissen, was Sie von dem Ansatz halten – ich wäre daran interessiert zu erfahren, wie Sie ihn verbessern oder anders angehen würden!
Ich mag diesen Ansatz, er ist ziemlich vielseitig und organisiert. Sie könnten sogar einen Build-Schritt verwenden, um eine Reihe von SVGs zu importieren und sie in eine Sass-Datei zu kompilieren.
Für die benutzerdefinierten Farben gehe ich normalerweise davon aus, dass es sich um ein maskiertes Element mit dem Hintergrund auf
currentColorhandelt: https://codepen.io/chriskirknielsen/pen/jOxGObqEin bisschen zerbrechlicher, aber ich denke, es sollte in den meisten Fällen funktionieren.
sehr gut
Wenn Sie das SVG als Bildmaske verwenden würden, könnten Sie den Elementhintergrund für alle Ihre Farbbedürfnisse verwenden. Das macht Hover-Zustände und Themewechsel auf der Website viel einfacher :)
Ich verwende auch Masken, und zwar über `clip-path`, weil sie sich richtig skalieren. Wahrscheinlich gibt es aber auch Nachteile.
Interessant.
Danke, Louis!
Z.
Ich bevorzuge die Verwendung von
clip-path: path('your-svg-path-here');Kein XML nötig...