Tutorial "Scalable Vector Graphics (SVG) in Webseiten"
© Silvia Rothen, rothen ecotronics, Bern, Schweiz
Autorin: Dr. Silvia Rothen, rothen ecotronics, Bern, Schweiz
Letzte Überarbeitung: 13.05.18
Seit HTML5 lassen sich Bilder nicht nur als Pixelgrafiken einbinden sondern auch als Vektorgrafiken. Das unterstütze Format heisst SVG, Scalable Vector Graphics.
Dieser Artikel geht auf Vor- und Nachteile der Verwendung von SVG gegenüber herkömmlichen Bildern ein und stellt die verschiedenen Möglichkeiten vor, wie man SVG in eine Webseite einbindet und sie mit CSS formatieren kann. Der Schwerpunkt liegt auf der direkten Einbindung von Symbol-Bibliotheken und deren Formatierung mit CSS.
Achtung: Leider erlaubt mein Provider z.Z. keine Einbindung von SVG-Dateien, deshalb sind gewisse Beispiele leider nicht sichtbar.
Inhaltsverzeichnis
- Einleitung
- Vorteile der Verwendung von SVG in Webseiten
- Nachteile der Verwendung von SVG in Webseiten
- Arten der Einbindung von SVG
- Arbeit mit Symbol-Bibliotheken
- Formatierung von SVG in Symbol-Bibliotheken mit CSS
- SVG-Animationen
- Tools
- Open-Source-Icon-Sammlungen
- Quellen
Einleitung
Schon seit längerer Zeit sieht man, dass im Web für Icons die traditionelle Einbindung von Bilddateien im PNG-, JPG- oder GIF-Format verdrängt wird durch IconFonts wie FontAwesome oder neuerdings auch durch SVG.
Vorteile der Verwendung von SVG in Webseiten
Weshalb sollte man überhaupt die bewährten Grafiken im JPG-, GIF- und PNG-Format durch SVG ersetzen? Ich sehe die folgenden Vorteile:
- SVG sind skalierbar, d.h. sie sehen in jeder Auflösung gestochen scharf aus
- Dieselbe SVG-Datei kann mit CSS in beliebigen Farben oder mit beliebigen Farbverläufen formatiert werden
- Bei SVG-Dateien mit mehreren Ebenenen lassen sich mit der geeigneten Technik die Ebenen einzeln formatieren (z.B. die Räder des Einkaufswagens in einer anderen Farbe als der Rest) oder Hover-Animationen mit einer Ebene anzeigen (z.B. öffnet sich der Deckel des Abfallkübels beim Darüberfahren)
- Dieselbe SVG-Datei kann mit CSS auch invertiert oder als Strichzeichnung (stroke) dargestellt werden
- Der Einsatz von SVG reduziert die Anzahl Requests für eine Webseite, sofern die SVG-Bilder intern gespeichert werden (siehe Einbindung)
- SVGs reduzieren die Dateigrösse einer Seite: Einfache SVG-Icons sind oft nur 100 bis 200 Bytes gross und das in jeder Auflösung. Damit können nur hochoptimierte PNG-Icons in einer Auflösung von 16x16 Pixel mithalten.
Nachteile von SVG
Auch wenn die Vorteile von SVG für Icons und ähnliches klar überwiegen, gibt es ein paar Nachteile:
- SVG eignet sich nicht für Fotos
- Die Einbindung von SVGs in Webseiten ist koplizierter als bei Pixelgrafiken, weil es mehr Möglichkeiten gibt
- Die Formatierungsmöglichkeiten mit CSS sind ungewohnt und abhängig von der gewählten Einbindung
- Die Formatierungsmöglichkeiten mit CSS sind nicht nutzbar, wenn SVG in CSS als Hintergrundgrafik eingebunden werden soll
- Nicht alles, was technisch möglich ist, funktioniert auf den aktuellen Browsern bereits richtig
Arten der Einbindung von SVG
Ich stelle hier kurz die verschiedenen Möglichkeiten der Einbindung von SVG vor, um mich dann im nächsten Kapitel mit jener Variante ausführlich zu beschäftigen, welche für meinen Anwendungsfall am geeignetsten ist. Für eine ausführliche Besprechung der verschiedenen Varianten mit ihren Vor- und Nachteilen sei auf das ausgezeichnete Buch "Responsive Webdesign" von Kai Laborenz und Andrea Ertel verwiesen (siehe Kapitel Quellen).
Alle in den Beispielen verwendeten Icons stammen aus der Open Iconic Library, die ich im Kapitel Open-Source-Icon-Sammlungen vorstelle, oder sind Weiterentwicklungen davon.
Einbindung als externe Datei mit img-Tag
Am nächsten an der traditionellen Einbindung von Icons ist sicher die Einbindung als externe Datei mit einem Image-Tag. Das einzige, was sich hier ändert, ist die Endung des Dateinamens.
HTML:
<img id="ecoStar01" class="ecoIcon" src="imagestmp/star.svg" alt="Favorit" title="Favorit"/>
CSS:
.ecoIcon { width: 50px; height: 50px; background-color: yellow; box-sizing: border-box; }
Auf diese Art hat man allerdings mit CSS nur die Möglichkeit, Höhe und Breite sowie den Hintergrund mit CSS zu stylen. Auf die SVG-Datei hat man dagegen keinerlei Einfluss.
Einbindung mit Embed- oder Object-Tag
Die Einbindung mit Embed oder Object quasi gleich aus. Vorteile sehe ich keine darin. Trotz des Namens "Embed" wird nämlich die SVG-Datei nicht in die Webseite eingebettet, es erfolgt also ein weiterer Request. Für das CSS gilt genau das gleiche wie oben, d.h. die Formatierungsmöglichkeiten sind beschränkt:
<embed id="ecoStar02" class="ecoIcon" src="imagestmp/star.svg"/>
Einbindung mit Object-Tag:
<object id="ecoStar03" class="ecoIcon" data="imagestmp/star.svg"></object>
Der einzige Vorteil dieser zwei Einbindungsmethoden, den ich bis jetzt gefunden habe, liegt darin, dass in den Developer Tools von Chrome der Text der SVG-Datei angezeigt wird. Mit CSS die Farbe ändern kann man aber trotzdem nicht.
Einbindung als Hintergrund-Grafik
In gewissen Situationen möchte man Grafiken nicht direkt einbinden, sondern als Hintergrundgrafik für andere Elemente, wie bisher auch:
HTML:
<form method="post"> <input id="ecoButton01" type="button" value="Button mit Hintergrundgrafik" /> </form>
CSS:
#ecoButton01 { width: 270px; height: 40px; background-repeat: no-repeat; background-position: right center; background-size: auto 80%; background-origin: content-box; background-image:url('imagestmp/star.svg'); }
Einbindung als Inline-Hintergrund-Grafik
Weil Provider z.T. das Hochladen und Anzeigen von externen SVG-Dateien auf ihren Webservern gesperrt haben, bindet der zweite Button die SVG-Grafik inline im CSS ein. Alle Formatierungen sind dieselben, nur die Zeile mit dem Background-Image ändert sich:
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228%22%20height%3D%228%22%20viewBox%3D%220%200%208%208%22%3E%0A%20%20%3Cpath%20d%3D%22M4%200l-1%203h-3l2.5%202-1%203%202.5-2%202.5%202-1-3%202.5-2h-3l-1-3z%22%20%2F%3E%0A%3C%2Fsvg%3E");
Wenn eine farbige SVG-Grafik eingebunden werden soll, dann müssen die Farben bereits in der SVG-Datei fix definiert sein. Es ist mir nicht gelungen, mit CSS-Variablen oder LESS-Variablen eine flexiblere Farbgebung zu erreichen. Wie man solche Inline-SVGs erzeugt, wird im Kapitel Tools erklärt.
Einbindung als Sprites
Wie normale Icons kann man auch SVG-Bilder als Sprites einbinden, damit man statt mehrere nur einen Request für die externen Grafiken benötigt (wie man das traditionellen Grafiken auch gemacht hat). Die SVG-Datei unten habe ich mit Inkscape aus den zwei SVG-Dateien star.svg und x.svg von Open Iconic zusammengesetzt.
So sieht die Sprite-Datei aus:
<svg id="ecoSprite01" version="1.1" viewBox="0 0 16 8" xmlns="http://www.w3.org/2000/svg"> <g> <path d="m4 0-1 3h-3l2.5 2-1 3 2.5-2 2.5 2-1-3 2.5-2h-3z" /> </g> <g> <path d="m9.56 0.169-1.41 1.41 0.72 0.72 1.78 1.81-1.78 1.78-0.72 0.69 1.41 1.44 2.53-2.53 1.78 1.81 0.69 0.72 1.44-1.44-0.72-0.69-1.81-1.78 2.53-2.53-1.44-1.41-0.69 0.72-1.78 1.78-1.81-1.78z"/> </g> </svg>
Direkt eingebunden:
HTML:
<div><i class="ecoIcon ecoSprite ecoSpriteStar">Favorit</i></div> <div><i class="ecoIcon ecoSprite ecoSpriteCross">Löschen</i></div>
CSS:
.ecoIcon { width: 50px; height: 50px; background-color: yellow; box-sizing: border-box; } .ecoSprite { background-image: url(imagestmp/spriteStarCross.svg); background-repeat: no-repeat; background-size: cover; text-indent: -9999px; display: block; } .ecoSpriteStar { background-position: 0 0; } .ecoSpriteCross { background-position: 100% 0; }
Erstes Icon aus der Sprite-Datei:
Zweites Icon aus der Sprite-Datei:
Diese Art der Einbindung von SVG-Sprites erscheint mir inzwischen bereits als veraltet, weil sie meines Erachtens gegenüber der Arbeit mit den unten vorgestellten Symbol-Bibliotheken keine Vorteile bringt.
Direkte Einbindung ins HTML
Wenn man mehr Formatierungsmöglichkeiten als in den bereits vorgestellten Einbindungsvarianten haben möchte, dann bleibt eigentlich nur die direkte Einbindung des SVG in die Seite. Das folgende Beispiel zeigt, wie man ein direkt eingebundenes SVG mit CSS einfärben und mit einer Kontur (stroke) versehen kann:
HTML:
<svg id="ecoStar06" class="ecoIcon" viewBox="0 0 8 8" preserveAspectRatio="xMinYMin meet"> <path d="M4 0l-1 3h-3l2.5 2-1 3 2.5-2 2.5 2-1-3 2.5-2h-3l-1-3z" /> </svg>
CSS:
.ecoIcon { width: 50px; height: 50px; background-color: yellow; box-sizing: border-box; } #ecoStar06 { fill: red; stroke: blue; stroke-width: 0.2; }
Arbeit mit Symbol-Bibliotheken
Die Einbindung von SVG als Symbol-Bibliotheken ist eine konsequente Weiterführung der direkten Einbindung: Die SVGs stehen direkt im HTML der Seite. Allerdings werden alle Icons als Symbols mit einer eindeutigen Id in einem versteckten SVG-Tag am Anfang der Seite definiert. Anschliessend wird mit dem use-Tag auf die einmal definierten Icons beliebig oft zugegriffen. Durch die direkte Einbindung spart man Requests und durch die Definition von Libraries wird nicht für jedes sich wiederholende Icon der ganze Text mit Pfad und evtl. Layers wieder in die Seite gebunden. Natürlich ist das nur von Vorteil für Icons, die mehr als einmal in die Seite eingebunden werden. Ansonsten ist die direkte Einbindung vorzuziehen.
Kombiniert man das ganze noch mit einer Technik, bei der die Icons z.B. als Ressourcen oder aus einer Datenbank eingebunden werden, dann kann man für verschiedene Kunden nicht nur verschiedenfarbige Icons einbinden, sondern auch solche mit unterschiedlichem Stil (etwas runder oder eckiger zum Beispiel).
Für die gängigen Icons in einem Standardshop scheint mir v.a. die Verwendung von Symbol-Libraries direkt in der Seite am Besten geeignet zu sein. Erstens reduziert man damit die Requests für eine Seite, da auf externe Dateien vollständig verzichtet wird. Durch die Verwendung von Symbol-Libraries am Anfang der Seite wird zudem das Icon selbst nur einmal eingebunden, was die Grösse der Seite erheblich reduziert, wenn dieselben Icons z.B. bei einer Artikelliste immer wieder vorkommen. Durch die direkte Einbindung behält man sich alle Formatierungsmöglichkeiten offen. Iim Gegensatz zu den anderen Varianten können auch Ebenen einzeln formatiert werden. Praktikabel ist dies allerdings v.a. bei den Farben, Versuche mit Verschiebungen (transform) führten auf verschiedenen aktuellen Browsern zu sehr unterschiedlichen Ergebnissen.
Definition einer Bibliothek mit zwei verschiedenen Icons:
<body bgcolor="#FFFFFF"> <!-- Hier ist die versteckte Library fuer SVG-Icons und Gradients --> <svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <!-- Erstes Icon Star --> <symbol id="ecoSymbolStar" viewbox="0 0 8 8" preserveaspectratio="xminymin meet"> <g><path d="M4 0l-1 3h-3l2.5 2-1 3 2.5-2 2.5 2-1-3 2.5-2h-3l-1-3z" /></g> </symbol> <!-- Zweites Icon Cross --> <symbol id="ecoSymbolCross" viewbox="0 0 8 8" preserveaspectratio="xminymin meet"> <g><path d="m9.56 0.169-1.41 1.41 0.72 0.72 1.78 1.81-1.78 1.78-0.72 0.69 1.41 1.44 2.53-2.53 1.78 1.81 0.69 0.72 1.44-1.44-0.72-0.69-1.81-1.78 2.53-2.53-1.44-1.41-0.69 0.72-1.78 1.78-1.81-1.78z"/></g> </symbol> </defs> </svg> ...
Einbindung des Star-Icons aus der Bibliothek
HTML:
<svg class="ecoIcon ecoStar"> <use xlink:href="#ecoSymbolStar"></use> </svg>
CSS:
.ecoIcon { width: 50px; height: 50px; background-color: yellow; box-sizing: border-box; } .ecoStar { fill: blue; stroke: red; stroke-width: 0.4; }
Einbindung desselben Icons mit anderer Class und damit Formatierung:
HTML:
<svg class="ecoIcon ecoStar2"> <use xlink:href="#ecoSymbolStar"></use> </svg>
CSS:
.ecoIcon { width: 50px; height: 50px; background-color: yellow; box-sizing: border-box; } .ecoStar2 { fill: green; background-color: gray; stroke: white; stroke-width: 0.3; border-radius: 4px; }
Einbindung des Lösch-Icons aus der Bibliothek:
HTML:
<svg class="ecoIcon ecoCross"> <use xlink:href="#ecoSymbolCross"></use> </svg>
CSS:
.ecoIcon { width: 50px; height: 50px; background-color: yellow; box-sizing: border-box; } .ecoCross { fill: red; padding: 10px; box-sizing: border-box; }
Noch schulde ich Ihnen den Beweis, das SVG-Icons in jeder Auflösung gestochen scharf aussehen:
15px | 25px | 50px | 100px |
Der einzige Unterschied bei diesen Icons ist, dass bei der Einbindung eine andere CSS-Klasse eingebunden wird, nämlich ecoIcon15x15, ecoIcon25x25, ecoIcon und ecoIcon100x100. Diese unterscheiden sich nur in der Definition von width und height.
Formatierung von SVG in Symbol-Bibliotheken mit CSS
Das war schon nicht schlecht, aber so richtig spassig wird die Arbeit mit SVGs, wenn man die Symbol-Bibliotheken mit Gradienten (Farbverläufen) ergänzt und bei SVGs mit mehreren Layers die Layer verschieden einfärbt.
Gradienten
Wie die SVGs selbst kann man Farbverläufe in der Bibliothek definieren und dann beliebig auf SVGs anwenden. Nach den symbol-tags werden
<svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <!-- Erstes Icon Star --> <symbol id="ecoSymbolStar" viewbox="0 0 8 8" preserveaspectratio="xminymin meet"> ... </symbol> <!-- Erster Farbverlauf radial von Gelb zu Rot --> <radialgradient id="ecoRg1" r="100%" cx="50%" cy="50%"> <stop stop-color="#FFDD00" offset="0" /> <stop stop-color="#990000" offset="0.9" /> </radialgradient> <!-- Farbverlauf linear von orange zu transparent --> <lineargradient id="ecoLg1"> <stop offset="0%" stop-color="orange" /> <stop offset="100%" stop-color="transparent" /> </lineargradient> </defs> </svg>
Hier wird auf das Star-Icon aus der Bibliothek einmal ein radialer Farbverlauf von gelb über orange zu rot angewendet und ein zweites Mal ein linearer Farbverlauf von orange zu transparent.
Für den radialen Gradienten:
HTML:
<svg class="ecoIcon ecoIconRg1"> <use xlink:href="#ecoSymbolStar"></use> </svg>
CSS:
.ecoIconRg1 * { fill: url(#ecoRg1); }
Und für den linearen Gradienten:
HTML:
<svg class="ecoIcon ecoIconLg1"> <use xlink:href="#ecoSymbolStar"></use> </svg>
CSS:
.ecoIconLg1 * { fill: url(#ecoLg1); }
Formatierung von Ebenen
Als erstes binden wir in die Bibliothek ein weiteres Symbol mit zwei Ebenen (g-Tags) ein.
<symbol id="ecoSymbolStarCross" viewbox="0 0 8 8" preserveaspectratio="xminymin meet"> <g style="fill: var(--colorStar, #bbbb00); display: inline"> <path d="m4 0-1 3h-3l2.5 2-1 3 2.5-2 2.5 2-1-3 2.5-2h-3z" /> </g> <g style="fill: var(--colorCross, #ff0000); display: inline; stroke-width:.51;"> <path d="m4.71 4-0.718 0.718 0.367 0.367 0.907 0.922-0.907 0.907-0.367 0.352 0.718 0.734 1.29-1.29 0.907 0.922 0.352 0.367 0.734-0.734-0.367-0.352-0.922-0.907 1.29-1.29-0.734-0.718-0.352 0.367-0.907 0.907-0.922-0.907z" /> </g> </symbol>
Leider funktioniert die intuive Vorgehensweise, die Layers im CSS über ihre Ids anzusprechen nicht, deshalb habe ich auch keine Ids vergeben. Wenn man Ebenen in SVGs verschieden einfärben möchte, dann muss man sie zuerst entsprechend vorbereiten, indem man für fill Variablen mit Defaultwerten setzt, z.B. var(--colorCross, #ff0000).
HTML:
<svg class="ecoIcon"> <use xlink:href="#ecoSymbolStarCross"></use> </svg>
Dank der Variablen lässt sich nun jede Ebene dieses Icons mit einer eigenen Farbe versehen. Die Einbindung ist abgesehen von der zusätzlichen CSS-Klasse ecoLayers gleich wie oben. Die Variablen --color... kann man nun nicht nur mit einzelnen Farben, sondern auch mit vorher definierten Farbverläufen füllen.
HTML:
<svg class="ecoIcon ecoLayers"> <use xlink:href="#ecoSymbolStarCross"></use> </svg>
CSS:
.ecoLayers { --colorStar: url(#ecoRg1); --colorCross: blue; }
Weitere Formatierungen
Während die Formatierung von SVGs mit Farben in fast allen modernen Browsern gut klappt, wird das Terrain wesentlich steiniger, wenn man mit transform arbeitet.
Dasselbe Icon in CSS horizontal gespiegelt mit "transform: scaleX(-1); "
oder vertikal gespiegelt mit "transform: scaleY(-1):
Hover-Animationen mit SVG
Eine einfache Animation kann darin bestehen, beim Hovern die Fill-Color und das Padding zu ändern und damit das Icon grösser zu machen.
Definition des SVG-Icons in der Bibliothek:
<symbol id="ecoSymbolHeart" viewbox="0 0 8 8" preserveaspectratio="xminymin meet"> <path style="fill: var(--colorHeart, #990000);" d="M2 0c-.55 0-1.04.23-1.41.59-.36.36-.59.85-.59 1.41 0 .55.23 1.04.59 1.41l3.41 3.41 3.41-3.41c.36-.36.59-.85.59-1.41 0-.55-.23-1.04-.59-1.41-.36-.36-.85-.59-1.41-.59-.55 0-1.04.23-1.41.59-.36.36-.59.85-.59 1.41 0-.55-.23-1.04-.59-1.41-.36-.36-.85-.59-1.41-.59z" transform="translate(0 1)" /> </symbol>
HTML:
<svg class="ecoIcon ecoHeart"> <use xlink:href="#ecoSymbolHeart"></use> </svg>
CSS:
.ecoHeart { padding: 15px; } .ecoHeart:hover { padding: 5px; --colorHeart: red; }
Eine weitere Animation beim Hovern könnte in einer Drehung bestehen:
SVG-Animationen
Aber mit SVG kann man nicht nur durch Hover ausgelöste Animationen erstellen, sondern auch solche, die automatisch ablaufen.
Animationen mit Farbe
Das erste Beispiel zeigt eine SVG-Animation, bei der ein Kreis regelmässig seine Farbe von Blau zu Rot und zurück wechselt.Achtung: Diese Animationen funktionieren im Internet Explorer und im Edge-Browser grösstenteils nicht!
Direkt eingebundenes SVG:
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"> <circle cx="50" cy="50" r="50"> <animate attributeName="fill" attributeType="XML" values="red;blue;red" dur="5s" repeatCount="indefinite"/> </circle> </svg>
Es funktioniert aber auch mit SVGs in Bibliotheken.
Definition des SVG-Icons in der Bibliothek:
<symbol id="ecoCircleAnimatedColors" viewbox="0 0 100 100" preserveaspectratio="xminymin meet"> <circle cx="50" cy="50" r="50"> <animate attributeName="fill" attributeType="XML" values="red;blue;red" dur="5s" repeatCount="indefinite"/> </circle> </svg>
HTML:
<svg class="ecoIcon ecoAnimation"> <use xlink:href="#ecoCircleAnimatedColors"></use> </svg>
CSS:
.ecoAnimation { padding: 5px; }
Pulsierender Kreis
Mit animate lässt sich jedes Attribut eines SVG animieren. Nach dem gleichen Prinzip kann man z.B. den Radius des Kreises zusätzlich grösser oder kleiner machen.
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"> <circle cx="50" cy="50" r="50"> <animate attributeName="r" attributeType="XML" values="30;40;50;40;30" dur="5s" repeatCount="indefinite"/> <animate attributeName="fill" attributeType="XML" values="red;blue;red" dur="5s" repeatCount="indefinite"/> </circle> </svg>
Rotierendes Zahnrad
Und natürlich lässt sich auch beides kombinieren: Indem man über das Zahnrad fährt, startet man die Animation.
Definition des SVG-Icons in der Bibliothek:
<symbol id="ecoCog"
viewbox="0 0 8 8" preserveaspectratio="xminymin meet">
<path d="M3.5 0l-.5 1.19c-.1.03-.19.08-.28.13l-1.19-.5-.72.72.5
1.19c-.05.1-.09.18-.13.28l-1.19.5v1l1.19.5c.04.1.08.18.13.28l-.5 1.19.72.72
1.19-.5c.09.04.18.09.28.13l.5 1.19h1l.5-1.19c.09-.04.19-.08.28-.13l1.19.5.72-.72-.5-1.19c.04-.09.09-.19.13-.28l1.19-.5v-1l-1.19-.5c-.03-.09-.08-.19-.13-.28l.5-1.19-.72-.72-1.19.5c-.09-.04-.19-.09-.28-.13l-.5-1.19h-1zm.5
2.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5-1.5-.67-1.5-1.5.67-1.5 1.5-1.5z"/>
</symbol>
HTML:
<svg class="ecoIcon ecoAnimationRotate"> <use xlink:href="#ecoCog"></use> </svg>
CSS:
.ecoAnimationRotate { animation-name: rotateCog; background-color: transparent; transform-origin: 25px 25px; animation-duration: 30s; animation-fill-mode: forwards; animation-timing-function: linear; animation-iteration-count: infinite; animation-play-state: paused; } @keyframes rotateCog{ to { transform: rotate(360deg); } } .ecoAnimationRotate:hover { animation-play-state: running; }
Pulsierendes Herz
Mit der gleichen Technik kann man auch aus dem herzförmigen SVG von weiter oben ein pulsierendes Herz machen, das erst noch die Farbe wechselt. Allerdings sieht man den Farbwechsel nur im neuesten Chrome und Edge, nicht aber im Firefox Version 56 oder in anderen älteren Browsern.
CSS:
.ecoAnimationScale { animation-name: scaleIcon; background-color: transparent; transform-origin: 25px 25px; animation-duration: 1s; animation-fill-mode: forwards; animation-timing-function: linear; animation-iteration-count: infinite; animation-play-state: paused; } @keyframes scaleIcon{ 0% { transform: scale( .5 ); } 50% { transform: scale( 1 ); --colorHeart: red; } 100% { transform: scale( .5 ); } } .ecoAnimationScale:hover { animation-play-state: running; }
Abfallkübel mit beweglichem Deckel
Definition des SVG-Icons in der Bibliothek:
<symbol id="ecoSymbolBin" viewBox="0 0 46 42"
preserveaspectratio="xminymin meet">
<g transform="translate(0,10)">
<path d="m4 10v20c0 1.1 0.9 2 2 2h18c1.1 0 2-0.9 2-2v-20zm6 18h-2v-14h2zm4 0h-2v-14h2zm4 0h-2v-14h2zm4 0h-2v-14h2z" />
</g>
<g>
<path
style="fill: var(--colorLid, #000000);transform:var(--transformLid, rotate(0deg))"
d="m26.5 14h-6.5v-2.5c0-0.825-0.675-1.5-1.5-1.5h-7c-0.825 0-1.5 0.675-1.5 1.5v2.5h-6.5c-0.825 0-1.5 0.675-1.5 1.5v2.5h26v-2.5c0-0.825-0.675-1.5-1.5-1.5zm-8.5 0h-6v-1.98h6z"
/>
</g>
</symbol>
HTML:
<div> <svg class="ecoIcon ecoBin"> <use xlink:href="#ecoSymbolBin"></use> </svg> </div>
CSS:
.ecoBin:hover {
--colorLid: red;
--transformLid: translateX(-7px) translateY(3px) rotate(340deg);
}
Tools
Möchte man gelegentlich ein Icon zeichnen, ohne viel Geld für die Lizenzen von InDesign hinzublättern, dann empfiehlt sich das Open-Source-Vektorzeichenprogramm Inkscape, das man hier downloaden kann.
Für gewisse Änderungen (z.B. zwei Ebenen in eine SVG-Datei kopieren) reicht auch ein Texteditor wie z.B. Notepad++.
Erstellen von Inline-SVG mit LESS
Wenn man LESS als Präprozessor einsetzt, dann lassen sich mit dem Befehl data-uri SVG-Dateien auf einfache Weise in Inline-SVGs für Hintergründe umwandeln. Entweder hat man LESS bereits in die Entwicklungsumgebung seiner Wahl eingebunden, dann passiert die Konvertierung im Normalfall automatisch. Wenn LESS bereits vorhanden ist, z.B. durch die Installation eines Plugins in Visual Studio Code oder Eclipse, dann kann man eine solche Konversion auch auf der Kommandozeile absetzen.
Zuerst ergänzt man eine LESS-Datei ecoSvg.less mit den entsprechenden Befehlen:
LESS/CSS:
.ecoInlineStar { background-image: data-uri("image/svg+xml;charset=UTF-8", "../open-iconic-master/svg/star.svg"); } .ecoInlineCart { background-image: data-uri("image/svg+xml;charset=UTF-8", "../open-iconic-master/svg/cart.svg"); } .ecoInlineStarColored { background-image: data-uri("image/svg+xml;charset=UTF-8", "../open-iconic-master/svg/starColored.svg"); }
Wenn die Hintergrund-Datei farbig sein soll, dann muss man das im SVG bereits fix definieren. Es scheint nicht möglich zu sein, hier CSS- oder LESS-Variablen zu verwenden.
SVG-Datei mit vordefinierten Farben:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8"> <path style="green; display: inline; stroke: white; stroke-width:.51;" d="M4 0l-1 3h-3l2.5 2-1 3 2.5-2 2.5 2-1-3 2.5-2h-3l-1-3z" /> </svg>
Dann setzt man auf der Kommandozeile z.B. den folgenden Befehl ab:
lessc C:\meinVerzeichnis\ecoSvg.less C:\meinVerzeichnis\ecoSvg.css
Wenn LESS installiert ist und die Verzeichnisse und Dateien korrekt angegeben wurden, erhält man dann im angegebenen Verzeichnis eine neue Datei ecoSvg.css, die so aussieht:
.ecoInlineStar { background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228%22%20height%3D%228%22%20viewBox%3D%220%200%208%208%22%3E%0A%20%20%3Cpath%20d%3D%22M4%200l-1%203h-3l2.5%202-1%203%202.5-2%202.5%202-1-3%202.5-2h-3l-1-3z%22%20%2F%3E%0A%3C%2Fsvg%3E"); } .ecoInlineCart { background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228%22%20height%3D%228%22%20viewBox%3D%220%200%208%208%22%3E%0A%20%20%3Cpath%20d%3D%22M.34%200a.5.5%200%200%200%20.16%201h1.5l.09.25.41%201.25.41%201.25c.04.13.21.25.34.25h3.5c.14%200%20.3-.12.34-.25l.81-2.5c.04-.13-.02-.25-.16-.25h-4.44l-.38-.72a.5.5%200%200%200-.44-.28h-2a.5.5%200%200%200-.09%200%20.5.5%200%200%200-.06%200zm3.16%205c-.28%200-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm3%200c-.28%200-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5z%22%0A%20%20transform%3D%22translate(0%201)%22%20%2F%3E%0A%3C%2Fsvg%3E"); } .ecoInlineStarColored { background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%208%208%22%3E%0A%20%20%3Cpath%20%0A%20%20%20%20style%3D%22fill%3A%20green%3B%20display%3A%20inline%3B%20stroke%3A%20white%3B%20stroke-width%3A.51%3B%22%20%0A%20%20%20%20d%3D%22M4%200l-1%203h-3l2.5%202-1%203%202.5-2%202.5%202-1-3%202.5-2h-3l-1-3z%22%20%2F%3E%0A%3C%2Fsvg%3E"); }
So sieht ein Button mit farbigem Hintergrund-SVG dann aus:
Das Beispiel verwendet übrigens Icons aus der Libray Open Iconic, die im nächsten Kapitel vorgestellt wird.
Die einzige funktionierende Vorgehensweise mit Variablen ist zweistufig. Zuerst wandelt man das SVG-Icon mit lessc in ein Inline-Icon um. Der erzeugte Code wird dann wieder in ein LESS-File geschrieben, wobei die Farbwerte, die ja im Klartext im Inline-Icon stehen, durch LESS-Variablen ersetzt werden.
@colorIStar: magenta; .ecoInlineStarWithVariable { background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%208%208%22%3E%0A%20%20%3Cpath%20%0A%20%20%20%20style%3D%22fill%3A@{colorIStar}%3Bdisplay%3Ainline%3Bstroke%3Awhite%3Bstroke-width%3A.51%3B%22%20%0A%20%20%20%20d%3D%22M4%200l-1%203h-3l2.5%202-1%203%202.5-2%202.5%202-1-3%202.5-2h-3l-1-3z%22%20%2F%3E%0A%3C%2Fsvg%3E"); }
Open-Source-Icon-Sammlungen
Nicht jeder ist ein begnadeter Zeichner und stürzt sich gleich auf Inkscape, um solche Icons selbst zu zeichnen. Für die gängigen Einsatzzwecke gibt es deshalb Open-Source-Iconsammlungen, die man meist auch für kommerzielle Zwecke nutzen darf, solange man die entsprechende Lizenz einbindet.
- Open Iconic finde ich persönlich die beste Sammlung: Sie enthält alle Icons, die ich benötige, in einem einheitlichen Stil. Ausserdem gibt es PNG-Icons in verschiedenen Grössen, falls man noch eine Fallback-Lösung für alte Browser einbauen möchte. Und die Lizenz erlaupt explizit auch das Verändern der Icons.
- FontAwesome ist in der neuesten Version nicht mehr eine reine Icon Library, sondern man kann auch eine Version mit JavaScript und SVG herunterladen. Mit dieser Library hat man sicher am wenigsten Einarbeitungsaufwand, wenn man bisher bereits mit IconFonts gearbeitet hat. Allerdings vergibt man sich dann auch gewisse CSS-Formatierungsmöglichkeiten.
- Bei IcoMoon kann man sich aus einer riesigen Sammlung die gewünschten SVG-Icons zusammenstellen. Allerdings sind längst nicht alle Open-Source, und da die Icons aus verschiedenen Quellen stammen, muss man für jede Quelle eine andere Lizenzerklärung durchlesen und bei Verwendung in eigenen Webseiten auch in die Seiten einschliessen. Achtung: Nicht jede Quelle erlaubt kommerzielle Nutzung oder Weiterbearbeitung der Icons.
Quellen
Die folgenden Publikationen fand ich für die Arbeit mit SVG besonders nützlich
- Kapitel 10 aus dem Buch "Responsive Webdesign" von Kai Laborenz und Andrea Ertel
- Eine gute Übersicht über die verschiedenen Arten, SVG einzubinden, befindet sich hier.
- Diesem Artikel verdanke ich den Trick, wie man auch mit Libraries verschiedene Ebenen mit verschiedenen Farben versehen kann: https://tympanus.net/codrops/2015/07/16/styling-svg-use-content-css
- Die Technik, wie man SVG-Animationen mit Hover startet, verdanke ich diesem Stackoverflow-Beitrag.
Diese Webseite wurde am 21.05.18 um 17:10 von rothen ecotronics erstellt oder überarbeitet.
Printed on 100% recycled electrons!