SVG/Tutorials/Icons
- jederzeit direkt bearbeitet werden können
- als Vektorgrafiken immer gestochen scharf skalierbar sind
- durch CSS und mit den Möglichkeiten von SVG mehrfarbig gestaltet, mit CSS-Filtern verändert und sogar animiert werden können.
- ebenfalls in Sprites zusammengefasst werden können. Das sind kleine Grafiken,[1] die als Icons Webseiten visuell bereichern, aber nicht im HTML auftauchen. Der Einsatz von SVG-Grafiken gegenüber CSS-Sprites oder Icon-Fonts hat mehrere Vorteile.
SVG-Grafiken sind …
- kleiner
- durch CSS formatierbar
- 100% responsiv und skalierbar
Neben der herkömmlichen Einbindung als Bild oder Hintergrundbild können Sie SVGs auch direkt im HTML-Markup einbinden.
Inhaltsverzeichnis
SVGs optimieren
Oft ist es schneller und einfacher, SVG-Grafiken mit einem Bildbearbeitungsprogramm wie Adobe Illustrator oder Inkscape zu erstellen und dann einzubinden. Allerdings sind viele im Netz vorhandene SVG-Icons mit Zeichenprogrammen wie Illustrator erstellt und daher unnötig kompliziert, wie dieses Beispiel aus dem Forum zeigt.[2]
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" height="160" width="160" version="1.0"> <g fill="#4b4b4b"> <path d="m80 15c-35.88 0-65 29.12-65 65s29.12 65 65 65 65-29.12 65-65-29.12-65-65-65zm0 10c30.36 0 55 24.64 55 55s-24.64 55-55 55-55-24.64-55-55 24.64-55 55-55z"/> <path d="m57.373 18.231a9.3834 9.1153 0 1 1 -18.767 0 9.3834 9.1153 0 1 1 18.767 0z" transform="matrix(1.1989 0 0 1.2342 21.214 28.75)"/> <path d="m90.665 110.96c-0.069 2.73 1.211 3.5 4.327 3.82l5.008 0.1v5.12h-39.073v-5.12l5.503-0.1c3.291-0.1 4.082-1.38 4.327-3.82v-30.813c0.035-4.879-6.296-4.113-10.757-3.968v-5.074l30.665-1.105"/> </g> </svg>
Sie können sie aber mit wenigen Schritten optimieren, sodass sie schneller vom Browser geladen werden.[3] Bei kleineren Grafiken kann dies von Hand geschehen, im Allgemeinen empfiehlt sich jedoch der Einsatz eines Code-Optimierers.
Verwenden Sie nur optimierte SVG-Grafiken, da …
- SVG-Grafiken keine Hardware-Unterstützung durch die Grafikkarte genießen
- der Code verständlicher wird
- es späteres Editieren vereinfacht.
überflüssige XML-Metadaten
Wenn Sie eine in Inkscape oder Illustrator erstellte Datei im Quelltext anschauen, sind die ersten 60 Zeilen weitgehend überflüssig:[4]
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="Neues Dokument 1">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2985" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="350"
inkscape:cy="520"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1018"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160">
<title>Seitenname</title>
<desc>aussagefähige Beschreibung</desc>
Die Breite und Höhe des SVG-Elements wird hier im CSS notiert, nur der Viewport wird durch das viewBox-Attribut festgelegt.
In HTML5 können Sie die XML-Dokumenttypdeklaration und die Namensräume des svg-Elements weglassen.
Daneben finden sich XML-Metadaten sowohl für Inkscape, als auch für den Vorläufer sodipodi, der seit 2004 nicht mehr weiterentwickelt wird,[5] und Metadaten im rdf-Format, die alle gelöscht werden können. Sie sind für die Anzeige von SVG-Grafiken nicht notwendig.
Präsentationsattribute
Grafik-Programme fügen oft für jedes Element Präsentationsattribute mit Standardwerten hinzu. Da die Browser diese Werte sowieso als Default rendern würden, können Sie sie auch löschen.
<path style="fill: black;
fill-rule: nonzero;
font-style: normal;
font-weight: normal;
fill-opacity: 1;
stroke-width: 1;
stroke-linecap: butt;
stroke-linejoin: miter;
stroke-miterlimit: 4;
stroke-opacity: 1;
stroke-dasharray: none;" />
Das optimierte Icon
Häufig ist es besser kreisrunde Formen nicht mit komplizierten Pfaden, sondern wirklich mit dem circle-Element zu realisieren.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 140">
<circle stroke="currentColor" stroke-width="10" cx="70" cy="70" r="60"/>
<circle cx="69" cy="39" r="11" fill="currentColor" />
<path fill="currentcolor"
d="M80 100c0 3 1.6 3.9 4 4l5 0.1v5h-38v-5l5-0.12.4-0.1 4-1 4-4v-31c0-4.4-6-4-9-3.9v-5l29-1"/>
</svg>
Durch die Farbangabe currentColor wird die Textfarbe des aktuellen Abschnitts automatisch übernommen. So können diese Icons ohne weitere Anpassung z. B. im Dark Mode verwendet werden.
SVG-Sprites
Ausgangspunkt war die Frage im SELF-Forum, ob man eine png-Grafik mit transparentem Hintergrund mittels CSS färben könne.[6] Dies ist so nicht möglich; für jede Farbe müsste eine Rastergrafik erstellt und gehostet werden, die dann bei einer Änderung des Farbkonzepts erneut angepasst werden müsste.
Gunnar Bittersmann postete ein Tutorial, das im Februar 2020 überarbeitet und ins SELF-Wiki übertragen wurde.[7]
SVG erstellen
Als erstes wird das PNG in einem Bildbearbeitungsprogramm geöffnet und die Koordinaten der Eckpunkte des Hauses ausgelesen. Die ergeben dann als Pfad:
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="house" viewBox="0 0 80 80">
<path d="M40,13 L1,48 H12 V80 H32 V56 H48 V80 H68 V48 H79z"/>
</symbol>
</svg>
Erwähnenswert ist, dass nicht das svg-Element, sondern das symbol-Element hier das viewBox-Attribut trägt. 0 0
heißt, dass der Punkt links oben der Punkt (0, 0), also der Koordinatenursprung ist. Die x-Achse zeigt nach rechts; die y-Achse nach unten.
Die anderen beiden Zahlen geben an, dass die Zeichenfläche 80 Einheiten breit und 80 Einheiten hoch ist. Ich habe die viewBox mal so gelegt, dass sie vom Haus weitgehend ausgefüllt wird: 0 0 80 80. Dann stehen die Häuser auf der Erde Grundlinie des Texts.
Wichtig ist hier, dass es sich bei SVG um eine Längeneinheit handelt, nicht um Pixel. Man würde dasselbe Ergebnis erhalten, wenn man 0 0 400 800 setzt und bei den Koordinaten alle x-Werte mit 5 und alle y-Werte mit 10 multipliziert.
Der Pfad:
-
M40,13
: Move to Punkt (40, 13) – die Spitze des Daches
-
L1,48
: Line to Punkt (1, 48) – das linke untere Ende des Daches
-
H12
: Horizontal line to x = 12, y bleibt gleich, d. h. zum Punkt (12, 48) – Hauswand links oben
(Ich hätte auch L12,48 schreiben können; das ist aber länger.)
-
V80
: Vertical line to y = 80, x bleibt gleich, d. h. zum Punkt (12, 80) – Hauswand links unten
(Ich hätte auch L12,80 schreiben können; das ist aber länger.)
usw. bis H79 zum letzten Punkt (80, 48) – rechtes unteres Ende des Daches -
z
: schließe die Kontur, d. h. Linie zurück zum Ausgangspunkt (40, 13) – der Spitze des Daches
SVG in HTML
Da SVG als XML-Dialekt direkt in HTML eingebunden werden kann, können Sie die Definitionen für Ihre Icons direkt in Ihre Webseiten integrieren. Das Ganze in eine HTML-Datei (in den body) gepackt und wir sehen … nichts! symbol ist nicht dazu gedacht angezeigt zu werden, sondern dazu, dass man sich das von anderswo holen kann.
Allerdings wird Platz für das svg-Element freigehalten. Da wir das nicht wollen, ergänzen wir die erste Zeile zu:
<svg style="display: none">
(Das hidden-Attribut gibt’s für svg-Elemente nicht; <svg hidden> funktioniert nicht.)
„Von anderswo holen“ heißt für uns jetzt: ein weiteres svg-Element.
<svg>
<use href="#house"/>
</svg>
use verwendet ein anderes Element und der Fragmentbezeichner (fragment-identifier) href="#house"
gibt an, welches. Das bezieht sich auf das Element mit der ID house – das ist das symbol im anderen svg-Element. (Dass IDs eindeutig sein müssen, also house
nicht als ID eines HTML-Elements in diesen HTML-Dokument auftreten darf, versteht sich von selbst.)
href
-Attribut ersetzt. Dies wird (Stand: August 2019) von allen Browsern (sogar IE9-11) verstanden - einzige Ausnahme bilden ältere Versionen des Safari-Browsers (iOS <12).
Da das
xlink:href
bestimmt nicht entfernt wird, ist es empfehlenswert, vorerst noch die eigentlich obsolete Variante zu verwenden.--Matthias Scharwies (Diskussion) 12:00, 1. Aug. 2019 (CEST)Zum Schluss sei noch erwähnt, dass bei in HTML eingebettetem SVG keine XML-Namenraumangaben nötig sind.
Et voilà! Das Haus sollte jetzt angezeigt werden – in irgendeiner Größe. Und in schwarz, weil wir im SVG keine Farbe angegeben haben. Das wollen wir auch nicht – dazu kommen wir später.
Und wenn wir dasselbe Icon nochmal haben wollen: noch ein svg mit use-Element. Als Beispiel gleich mit etwas Text drumrum:
<p>
Home
<svg>
<use href="#house"/>
</svg>
<a href="">
sweet home
<svg>
<use href="#house"/>
</svg>
</a>
</p>
SVG mit CSS gestalten
Nun wollen wir nicht irgendeine Größe; und auch die Farbe festlegen. Das können wir im Stylesheet tun, wo bspw. auch die Angaben zur Farbe von Links einschließlich Hover- und Focus-Effekt (für Tastaturbedienung!) stehen:
a { color: steelblue }
a:focus, a:hover { color: red; }
svg {
width: 1em;
height: 1em;
fill: currentColor;
}
Für SVG-Elemente gibt es teilweise andere CSS-Eigenschaften als für HTML-Elemente, wie hier fill. Damit können wir die Icons mit einer Farbe füllen, bspw. fill: rebeccapurple
.
Wir können aber auch mit dem Schlüsselwort currentColor für die Icons jeweils die aktuelle Textfarbe übernehmen. In unserem Beispiel ist das für das erste Haus schwarz und für das zweite – wo das svg innerhalb des a-Elements ist – steelblue
.
Und wenn sich beim Drüberfahren mit der Maus oder Fokussieren mit der Tastatur die Farbe des Links auf red;
ändert, dann ändert sich die Farbe des Icons mit!
Aber eigentlich soll gar nicht alles SVG in HTML eingebettet sein.
Einbindung externer svg-Dateien
Was, wenn wir nun mehrere verschiedene Icons haben: Mein Haus, mein Auto, mein Boot, …?
Die sammeln wir alle als symbols im ersten svg-Element:
<svg style="display: none">
<symbol id="house" viewBox="0 0 96 96">
<path d="M40,13 L1,48 H12 V80 H32 V56 H48 V80 H68 V48 H79z"/>
</symbol>
<symbol id="car" viewBox="0 0 100 200">
<path d="…"/>
</symbol>
<symbol id="boat" viewBox="-21 -21 42 42">
<path d="…"/>
</symbol>
</svg>
Die Pfade für Auto und Boot habe ich nur angedeutet. You get the picture. (No pun intended.)
Wichtig ist, dass jedes symbol sein eigenes viewBox-Attribut, d. h. sein eigenes Koordinatensystem hat. Das hat nichts mit der Größe zu tun, mit der das Icon dargestellt wird; diese hatten wir im Stylesheet mit svg { width: 1em; height: 1em }
angegeben.
(Man kann natürlich auch für verschiedene Icons verschiedene Größen angeben oder dasselbe Icon an verschiedenen Stellen in verschiedenen Größen verwenden.)
<ul>
<li><svg><use href="#house"/></svg> mein Haus</li>
<li><svg><use href="#car"/></svg> mein Auto</li>
<li><svg><use href="#boat"/></svg> mein Boot</li>
</ul>
Nun wollen wir die Icons nicht nur auf einer Webseite, sondern auf allen Seiten unserer Website einsetzen. Dazu müssten wir das svg-Element mit den symbols in jedes HTML-Dokument hineinkopieren … was wohl keine so gute Lösung wäre.
Sinnvoll ist, das svg-Element mit den symbols in eine Datei auszulagern (bspw. speichern als icons.svg). style="display: none"
kann dann weg; wichtig ist, dass hier die XML-Namensraumangabe vorhanden ist:
<svg xmlns="http://www.w3.org/2000/svg">
Diese Datei wird nun nicht mit PHP o.ä. in den HTML-Quelltext geschrieben, denn dann müssten ja sämtliche Icons bei jeder Seite erneut übertragen werden. Das würde den Quelltext unnötig aufblähen, insbesondere, wenn wir nicht nur drei, sondern dreiundzwölfzig Icons in unserer Sammlung haben.
Wir wollen, dass diese SVG-Datei mit allen Icons nur einmal übertragen wird und dann im Browsercache liegt. Wir holen uns die Icons deshalb aus der externen Datei:
<ul>
<li><svg><use href="/assets/icons.svg#house"/></svg> mein Haus</li>
<li><svg><use href="/assets/icons.svg#car"/></svg> mein Auto</li>
<li><svg><use href="/assets/icons.svg#boat"/></svg> mein Boot</li>
</ul>
bzw.
<ul>
<li><svg><use href="https://example.net/assets/icons.svg#house"/></svg> mein Haus</li>
<li><svg><use href="https://example.net/assets/icons.svg#car"/></svg> mein Auto</li>
<li><svg><use href="https://example.net/assets/icons.svg#boat"/></svg> mein Boot</li>
</ul>
Wenn man die Icons zusätzlich zu vorhandem Text einsetzt (was generell eine gute Idee ist), kann man auf progressive enhancement setzen: Wenn die Bilder nicht geladen werden, ist das sollte nicht tragisch; die Icons sind ja „nur“ Zusatz zum Text.
Damit steht der Verwendung von SVG-Icons nichts im Wege. Und es gibt keinen Grund für Icon-Fonts mehr. Keinen!
- Alle SVG-Icons sind in einer Grafik integriert und benötigen so nur einen HTTP-Request.
- Diese Grafik-Datei wird nach dem ersten Aufruf im Cache gespeichert.
mehrfarbige, animierte Icons
einheitlicher CSS-Stil
Durch die Möglichkeit die Präsentationsattribute der SVG-Elemente in CSS in Klassen zusammenzufassen, können Sie Multi-Color-Icons mit einem einheitlichen Erscheinungsbild gestalten.
<a href="" xlink:href="">
<desc>Icon für Home-Button</desc>
<rect class="background" x="1" y="1" width="59" height="59" />
<rect x="10" y="35" width="40" height="24" fill="#ccc" stroke="black" stroke-width="0.5" />
<rect x="40" y="15" width="5" height="15" fill="black" />
<path d="M8,35 l22,-20 l22,20 z" fill="#c32e04" stroke="black" stroke-width="0.5" />
<rect x="15" y="45" width="8" height="14" class="window" stroke="black" stroke-width="0.5" />
<rect x="35" y="45" width="8" height="8" class="window" stroke="black" stroke-width="0.5" />
</a>
S
Animationszustände
Die obigen Icons sind interaktiv: Wenn Sie durchtabben oder mit der Maus über die Links fahren, werden :hover
und :focus
aktiviert.
.background {
fill: none;
}
a:hover .background,
a:focus .background {
fill: #fffbf0;
stroke: #e7c157;
stroke-width:1;
}
.window {
fill: #666;
}
a:hover .window,
a:focus .window {
fill: #dfac20;
}
<a href="" xlink:href="">
<desc>Icon für Home-Button</desc>
<rect class="background" x="1" y="1" width="59" height="59" />
...
<rect x="15" y="45" width="8" height="14" class="window" stroke="black" stroke-width="0.5"/>
<rect x="35" y="45" width="8" height="8" class="window" stroke="black" stroke-width="0.5"/>
</a>
:hover
und :focus
erhält es eine gelbe Füllung, die als Hintergrund für das Icon wirkt.Siehe auch
Sie können SVG-Sprites auch als Hintergrundbilder in ein Stylesheet einbinden. Dabei könen Sie entweder das SVG-Markup inline ins CSS notieren als auch Teile einer SVG-Grafik über den Fragmentbezeichner (fragment-identifier) identifizieren und referenzieren.
Hauptartikel: SVG/Tutorials/Einstieg/Einbindung#Inline-SVG im CSS
Weblinks
- ↑ Wikipedia: Sprite (Computergrafik)
- ↑ SELF-Forum: .png Icon durch .svg ersetzen vom 29.11.2021
- ↑ CSS-Tricks.com Understanding and Manually Improving SVG Optimization von Raymond Schwarz 18.05.2015
- ↑ http://demosthenes.info/blog/807/SVG-Optimisation-The-Basics
- ↑ Wikipedia: Sodipodi
- ↑ SELF-Forum: Icon, png mit transparenten Hintergrund mittels CSS färben vom 23.08.2018
- ↑ SELF-Forum: Tutorial vom 24.08.2018
englisch:
- css-tricks: SVG `use` with External Reference, Take 2 von Chris Coyier
- css-tricks: Inline SVG vs Icon Fonts von Chris Coyier
- css-tricks: svg-fragment-identifiers work
- ccs-tricks: SVG `symbol` a Good Choice for Icons
- Tyler Sticka: Seriously, Don’t Use Icon Fonts
- 24ways: An Overview of SVG Sprite Creation Techniques von Sara Soueidan
- broken-links: better-svg-sprites-with-fragment-identifiers
- broken-links: fragment-identifiers
- Ian Feather: Ten reasons we switched from an icon font to SVG
- stackoverflow: how to use SVG sprite sheet as css background image while maintaining aspect-ratio
- tutsplus.com: Manipulating SVG Icons With Simple CSS
- edward-designer.com: Use SVG in Websites Now – a How-to Guide
- Noah Blon: SVG Weather Icons Animated with CSS
- Etsy’s Evolving Icon System sehr ausführlicher und informativer Artikel über Entstehung und Prinzipien des etsy-Frameworks, das sehr gelungene SVG-Icons zur Verfügung stellt (und natürlich selbst erweitert werden kann)
Sprite-Generator:
- github: grunt-svgstore
- github: SVG Sprite
SVG Sprite is a Node.js module, which optimizes a bunch of SVG files, and bakes them into SVG sprite-types including traditional CSS sprites for background and/or foreground images, SVG stacks and more.
Beispiele
Code-Optimierer
Mittlerweile gibt es mehrere Möglichkeiten, durch Grafik-Programme erstellte SVG-Grafiken nachträglich zu optimieren.
Am sinnvollsten ist die Entfernung der Namespace-Deklarationen und Reduzierung der Dezimalstellen bei Attributen und Stildeklarationen. Leere Elemente und Gruppierungen werden entfernt, sowie Pfade zusammengefasst.
- SVGOMG von Jake Archibald funktioniert online und hat Einstellungen wie z. B. das Reduzieren von Farben und Entfernen überflüssiger stroke- und fill-Eigenschaften.
Sie können SVGOMG auch speichern und offline verwenden. - SVGO ist ein node-basiertes Kommandozeilenwerkzeug, mit dem Sie ebenfalls SVG-Grafiken aufräumen können.
- github: SVG Cleaner