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

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.

Zurück zum Inhaltsverzeichnis


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:

Nachteile von SVG

Auch wenn die Vorteile von SVG für Icons und ähnliches klar überwiegen, gibt es ein paar Nachteile:

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;
}
Favorit

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:

Favorit

Zweites Icon aus der Sprite-Datei:

Löschen

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;
}

 

Zurück zum Inhaltsverzeichnis


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.

Zurück zum Inhaltsverzeichnis


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:

Zurück zum Inhaltsverzeichnis


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;
}
Fahren Sie mit der Maus über das Zahnrad, um die Animation zu starten.

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;
}
Fahren Sie mit der Maus über das Herz, um die Animation zu starten.

Abfallkübel mit beweglichem Deckel

Und jetzt noch die Lektion für Fortgeschrittene: Beim Hovern über dem Trash-Icon soll sich der Deckel heben. Das Icon befindet sich dabei in einer Symbol-Bibliothek. Die Schwierigkeit gegenüber einer direkten Einbindung des SVG besteht darin, dass nicht mehr direkt auf den Layer mit dem Deckel zugegriffen werden kann. Ausserdem kommt es beim Rotieren des Deckels zu einer Verschiebung nach rechts, die es bei der direkten Einbindung ebenfalls nicht gibt. Die einzige funktionierende Variante war wieder jene mit Variablen. Allerdings funktioniert es nur mit Chrome und Firefox, EDGE und IE zeigen nur die Farbänderung, nicht aber die Bewegung.

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);
}
Der Deckel hebt sich, wenn Sie mit der Maus über das Icon fahren.

Zurück zum Inhaltsverzeichnis


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");
}

Zurück zum Inhaltsverzeichnis


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.

Zurück zum Inhaltsverzeichnis


Quellen

Die folgenden Publikationen fand ich für die Arbeit mit SVG besonders nützlich



Diese Webseite wurde am 03.05.18 um 22:34 von rothen ecotronics erstellt oder überarbeitet.

Impressum

Zurück zu rothen ecotronics

Printed on 100% recycled electrons!