Zur Realisierung von Webanwendungen sind viele von uns mit zahlreichen Werkzeugen, Arbeitsabläufen oder Frameworks vertraut, um die verschiedensten Anforderungen an das Schreiben von Quellcode umzusetzen. Betreten wir einen Bereich, in dem es weniger um Code als vielmehr darum geht, statische, grafische Artefakte in unseren Anwendungen performant und vor allem wartbar zu integrieren, sind wir das wohl etwas weniger gewohnt. Hier greifen wir häufig zu fertigen Lösungen von Drittherstellern, die jedoch mit Einschränkungen einhergehen. Doch wie kann man vorgehen, wenn man diese Herausforderung selbst lösen möchte? Wie gehen wir systematisch damit um, wenn wir eine Designvorgabe vorliegen haben, auf dem individuell entworfene Icons den Weg in unsere Applikation finden sollen?

In diesem Artikel lernen Sie hilfreiche Konzepte, praktische Werkzeuge und einen effizienten Ablauf kennen, um Icons auf zeitgemäße Art und Weise in Ihre Webanwendung integrieren.

Icons im Web

Moderne Webseiten und Applikationen bestehen aus viel Weißraum, Flächen und recht wenig Text. Der Mensch von heute ist es gewohnt, Informationen kurz, prägnant und gebündelt aufzunehmen. Ein wesentlicher Bestandteil dessen sind Icons. Ein Icon ist eine vereinfachte, visuelle Darstellung eines mitunter abstrakten Sachverhalts. Bei der Nutzung auf Schaltflächen verkürzt es die Informationsübermittlung von Texten auf wenig Bildschirmplatz. Oder es reichert Text an, sodass durch doppelte Kodierung Informationen schneller verarbeitet werden können.

Um Icons in der eigenen Anwendung zu nutzen, kann man sich an zahlreichen kostenlosen oder -pflichtigen Bibliotheken bedienen oder sich selbst welche erstellen (lassen). Dabei gibt es technisch gesehen mehrere Formate, in denen Icons vorliegen und genutzt werden können.

Rastergrafiken

Rastergrafiken – wie beispielsweise JPEG oder PNG – zeichnen sich dadurch aus, dass die Bildinformation, vereinfacht gesagt, eins zu eins übermittelt wird. Eine Rasterbild mit einer Größe von 100 x 100 Pixeln enthält eine Matrix aus je 100 X- und Y-Koordinaten und des darzustellenden Wertes zum Beispiel im RGB-Format (schematisch dargestellt in der folgenden Abbildung).

Abbildung SCG-Sheets - Bildinformationen in einer Rastergrafik

Bildinformationen in einer Rastergrafik (Quelle: https://commons.wikimedia.org/wiki/File:Rgb-raster-image.svg)

Dies bedeutet wiederum, dass die Grafik zunächst in genau einer festen Größe vorliegt. Braucht man eine kleinere oder größere Abbildung, muss man entweder eine weitere Grafik in der passenden Größe erzeugen oder die vorhandene Grafik skalieren. Fehlende Pixelwerte in der Matrix müssen algorithmisch befüllt werden, wodurch es zu Informationsverlust und Unschärfen kommen kann.

Aus diesem Grund werden Rastergrafiken heutzutage in Webseiten und -applikationen häufig nur da genutzt, wo es wenig Größen- oder Farbveränderungen zu erwarten gibt, bzw. die enthaltene Bildinformation sehr komplex ist, wie beispielsweise bei Fotografien.

Vektorgrafiken

Im Gegensatz zu Rastergrafiken ist die Bildinformation in Vektorgrafiken eher eine Art Beschreibung von zu zeichnenden Elementen. Ein etabliertes Format sind hier SVGs (Scalable Vector Graphics). Die in einem SVG befindlichen Informationen beschreiben nicht das Endergebnis in Pixelwerten, sondern maschinenlesebare Instruktionen, wie man zu diesem Endergebnis gelangt. Diese Anweisungen sind darüber hinaus nicht unbedingt an absolute Größenwerte gebunden. Dadurch sind Vektorgrafiken prinzipiell größenunabhängig und damit artefaktfrei skalierbar. Wie in Abbildung 2 und dem dazugehörigen Code-Ausschnitt 1 zu sehen, sind alle Einzelelemente innerhalb dieser Beschreibung adressierbar und lassen sich damit nachträglich, beispielsweise zur Laufzeit einer Applikation, anpassen.

Abbildung SVG-Sheets - Eine einfache SVG Vektorgrafik.

Eine einfache SVG Vektorgrafik.

Die Dateigröße eines SVGs ist abhängig von der Komplexität der darin enthaltenen Zeichenbeschreibungen und unabhängig von der Größe des darzustellenden Bildes. Zudem sind SVGs flexibel anpassbar in Größe und Farbe. Icons oder schematische Abbildungen im modernen Web werden daher häufig über Vektorgrafiken realisiert. Logos oder schematische Abbildungen werden dabei nur in ihrer Größe, nicht aber ihrer Farbe verändert. Icons sind meist einfarbig, wobei sie in unterschiedlichen Größen und Einfärbungen genutzt werden, zum Beispiel, um den Klick- oder Mouseover- vom Normal-Zustand abzugrenzen.

Vom Design zur Umsetzung

Wir wollen uns nun ein praktisches Beispiel ansehen, bei dem Grafiken im Vektorformat eingesetzt werden sollen, und klassifizieren die dort genutzten Grafiken. Darauf aufbauend schauen wir uns an, wie wir einen pragmatischen Arbeitsablauf etablieren und verschiedene Werkzeuge einsetzen, um Icons generell in unseren Projekten zu handhaben.

Beispielapplikation

Abbildung SVG-Sheets - Login-Seite einer Beispiel-Webanwendung zur persönlichen Musikverwaltung

Login-Seite einer Beispiel-Webanwendung zur persönlichen Musikverwaltung.

Das Logo ist mehrfarbig, sogar mit Verläufen, und soll in seinen Farben stets so erhalten bleiben. Es wird meist in dieser Größe von 128px verwendet. Es wird sich kaum verändern. Wir bezeichnen dieses recht starre Asset als Illustration.Abbildung 3 zeigt den Entwurf einer Login-Seite für eine Webanwendung zur persönlichen Musikverwaltung. Stellen wir uns vor, dass wir diesen Entwurf von einer/-m Design-Kollegin/-en bekommen haben und diesen nun umsetzen sollen. Wir können darauf drei verschiedene Grafik-Assets erkennen: Das große bunte Logo oben links, das orangene Warnsymbol bei fehlerhafter Passworteingabe und das weiße Icon auf der Login-Schaltfläche. Alle Grafiken liegen uns aus dem Design als SVGs vor. Man kann diese nun unterschiedlich klassifizieren:

  • Die beiden anderen Grafiken sind einfarbig. Sie sind je nach Anwendungsfall auch in anderen Bereichen der Anwendung meist zwischen 12 und 48 Pixel groß und können in verschiedenen Farbgebungen vorkommen. Diese dynamisch einsetzbaren, kleinen monochromen Assets bezeichnen wir als Icons.

In einer Webapplikation gibt es häufig viele verschiedene Icons, die je nach Einsatzzweck in unterschiedlicher Farbe (Umgebungsfarbe, Anwendungsstatus, Interaktionen wie Mouseover oder Klick) oder Größe (Verwendung in einem Eingabefeld, auf Schaltflächen, in Seitenleisten) genutzt werden. Wir wollen uns anschauen, wie wir diese Icons in unserer Webapplikation verwalten, diese nutzen und je nach Anforderung zur Laufzeit verändern können.

Nutzung von SVG-Icons

Als erstes können wir in unserem Webprojekt unsere Illustrationen und Icons als einzelne SVG-Dateien in speziellen Ordnern ablegen, z.B. /assets/illustrations und /assets/icons. Je nachdem, ob wir ein Framework verwenden oder wie unsere Anwendung aufgebaut ist, gestaltet sich der Zugriff auf diesen Ordner unterschiedlich. Um die SVGs nun zu verwenden, können wir beispielsweise ein HTML Image-Tag verwenden (siehe Code-Beispiel 2).

Unsere Illustration (das App-Logo) können wir exakt so einbinden, denn wir nutzen es nur genau einmal an dieser Stelle und ändern seine Farbe niemals. Tun wir das gleiche für die Login-Schaltfläche, so fällt auf, dass wir die ursprüngliche schwarze Füllfarbe des SVGs eigentlich anpassen müssten.

Abbildung SVG-Sheets - Einsatz des originalen SVGs im src-Attribut des HTML img-Tags

Einsatz des originalen SVGs im src-Attribut des HTML img-Tags.

Ohne die ursprüngliche SVG-Datei zu verändern, rein über CSS, ist dies mit dem Image-Tag allerdings nicht möglich. Über die CSS Eigenschaft mask ist das grundsätzlich machbar (siehe Codebeispiel 3). Dieses Feature wird von den meisten modernen Browsern (zum Teil durch Präfixes) unterstützt, allerdings fühlt es sich eher wie ein Workaround als eine Lösung an.

Bei der Verwendung vieler einzelner SVGs gibt es noch einen weiteren großen Nachteil: Jede einzelne Ressource muss vom Browser geladen werden. Dies wird besonders dann auffällig, wenn beispielsweise ein modaler Dialog geöffnet wird, auf dem wiederum mehrere Icons verwendet werden. Hier kommt es recht schnell zu dem Effekt, dass die darauf genutzten Icons erst nach einer kurzen, aber vom Nutzer merkbaren Zeit erscheinen und so ein Flimmern wahrnehmbar ist. Dies kann man nur umgehen, indem man alle Icons bündelt und einmalig, beispielsweise beim Start der Anwendung, vorlädt.

Icon-Fonts

Die Anforderung, viele Icons in einer Anwendung komfortabel als einen gebündelten Satz einzubinden, später per ID anzusprechen und Farbe sowie Größe über CSS anpassen zu können, trifft auf viele Webanwendungen zu. Da dies konzeptionell ähnlich erscheint wie die Verwendung von Schriftarten, kam man auf die Idee, aus einem Satz von Icons einen Font zu erzeugen, dabei jedem Icon einen Letter daraus zuzuordnen und die Icons später über die Schriftgröße und -farbe zu verändern. Viele Icon-Bibliotheken, wie z.B. Font Awesome (trägt dies sogar in seinem Namen), setzen dies genauso um: Zur Verwendung bindet man einen speziellen Font ein, bekommt ein entsprechendes CSS dazu, welches die Abbildung der Letter auf CSS-Klassennamen vollzieht, und muss die CSS-Klassen dann auf ein ausgewähltes HTML-Tag anwenden (siehe Code-Beispiel 4).

Möchte man nicht eine bestehende Bibliothek, sondern seine eigenen Icons nutzen, muss man sich einen ebensolchen Font selbst erzeugen. Die Auswahl an Werkzeugen, die man in den eigenen Build-Prozess integrieren kann, ist sehr eingeschränkt. Man stößt bei Recherchen schnell auf Online-Tools wie beispielsweise IcoMoon.

Abbildung SVG-Sheets - Import und Verwaltung der Icons im Online-Tool IcoMoon

Import und Verwaltung der Icons im Online-Tool IcoMoon.

Auf den ersten Blick ist dieses Werkzeug einfach zu benutzen, um sich hieraus einen Font erzeugen zu lassen. Es ist jedoch eine große Herausforderung, so ein externes Tool in einen möglichst automatisierten und zugleich kollaborativen Workflow zu integrieren, denn genau an dieser Schnittstelle können schnell Inkonsistenzen auftreten.

Selbst wenn wir mit NPM-Paketen wie Fantasticon die Font-Erzeugung in unser Projekt integrieren können, bleiben ein paar negative Eigenschaften, die mich persönlich immer dazu verleitet haben, nach anderen Möglichkeiten zu schauen.

Eine Schriftart statt echte grafische Assets zu verwenden und diese dann über speziell gewählte HTML-Elemente wie das i-Tag zu adressieren und zu stylen, fühlt sich wie die o.g. Lösung über die CSS-Maske eher wie ein Workaround an. Es fällt schwer, Bezüge zwischen dem ursprünglichen Icon, seinem Letter im binären Font-Format sowie die im CSS hinterlegte semantisch sinnvoll benannte CSS-Klasse herzustellen. Dabei den Überblick zu behalten, kann durchaus eine Herausforderung sein. Zu guter Letzt dürfen solche Icons immer nur einfarbig sein. Die dahinterliegende Technologie einer Schriftart erlaubt keine Einfärbung unterschiedlicher Teilbereiche.

SVG-Sheets

Um möglichst alle Vorteile des Icon-Fonts und einzelner SVG-Dateien zu kombinieren, schauen wir uns nun ein etwas weniger bekanntes, aber durchaus nützliches Feature an: das SVG Sheet.

Wir wollen den Bezug zu grafischen Assets beibehalten und nutzen daher direkt in HTML eingebettetes SVG, was mittlerweile von allen modernen Browsern unterstützt wird. Um aber nicht mit Verweisen auf Einzel-SVGs im HTML umgehen zu müssen und gleichzeitig die Menge an Webanfragen zu reduzieren und so einen deutlichen Performancegewinn zu bekommen, bündeln wir alle Grafiken zu einem großen SVG. Jeder Teil-Grafik wird dabei eine ID gegeben, welche wir aus dem ursprünglichen Dateinamen ableiten. Zuletzt verwenden wir innerhalb der SVG-Tags das use-Tag, welches mittlerweile recht gute Browserunterstützung bietet, um auf einzelne SVGs innerhalb unserer großen SVG-Tapete zuzugreifen.

Verwendung von SVG-Sheets

Code-Beispiel 5 zeigt, wie wir letztlich unser Grafiken aus dem Sheet im HTML unserer Webanwendung nutzen möchten.

Aus rein semantischer Perspektive ist sehr explizit, was hier passiert: Wir möchten an dieser Stelle im DOM das SVG mit der ID Icon.Login als Ausschnitt aus einem größeren SVG anzeigen, das unter der URL dist/assets/icons.svg erreichbar ist.

Darüber hinaus möchten wir, wie in Code-Beispiel 6 gezeigt, über CSS das Aussehen der Icons bestimmen. Wir sprechen das SVG-Tag daher z.B. über eine CSS-Klasse an, vergeben häufig global einen Standardstil für alle unsere Icons, können aber für Ausnahmefälle (wie hier das Warnungs-Icon) diesen Stil überschreiben.

Es fällt auf, dass im Gegensatz zu der Nutzung eines Icon-Fonts hier keine besonderen technischen Workarounds notwendig sind. Der Verweis auf die Icons sowie das Styling sind sehr direkt und nachvollziehbar.

Aufbau von SVG-Sheets

In Code-Beispiel 7 sehen wir, wie so ein hierzu notwendiges SVG-Sheet aussieht. Es ist eine einzige SVG-Datei mit einer Menge von per ID benannten symbol-Elementen, die wiederum Elemente vom Typ path enthalten. Die Symbole ermöglichen es, die SVG-Teilbereiche von außen über das use-Element zu adressieren. Innerhalb des Symbols beschreiben die Pfade die Form des eigentlichen Icons.

Wie kommt man nun ausgehend von einzelnen SVG-Grafiken – vor allem ohne viele manuelle Schritte und reproduzierbar – zu einem solchen Sheet? In größeren Projekten arbeiten meist mehrere Menschen an der Erzeugung und Nutzung der Icons. Es ist essentiell für solche Fälle, dass ein möglichst konsistenter, automatisierter Prozess existiert.

Automatisierung

Mit Hilfe von NPM, seinen Skript-Möglichkeiten und ein paar Bibliotheken möchten wir den Schritt zum Erstellen des SVG-Sheets automatisieren. Dabei möchten wir folgende Eigenschaften berücksichtigen:

  • Die ursprünglichen Icon-Assets aus dem Design sollen im Projekt abgelegt werden.
  • Diese originalen Assets möchten wir nicht manuell anpassen müssen.
  • Die Dateinamen sollen auf IDs abbilden, die wir später nutzen, um Icons zu adressieren.
  • Die automatisierte Erzeugung des Sheets sollte schnell, direkt und während eines möglichen Builds unserer Applikation reproduzierbar ausgeführt werden können.

In unserem Projekt wählen wir zunächst einen bestimmten, dem Team bekannten Ordner, in dem wir die Einzel-SVGs versioniert ablegen, beispielsweise unter assets/icons. Über die verschiedenen Git-Hosting-Anbieter können auch Designer/-innen ohne viel technischen Hintergrund ihre Ergebnisse dort unkompliziert ablegen. Sie sollten ledigliche auf eine gute Dateibenennung achten.

Als nächsten Schritt möchten wir nun automatisiert alle Icons aus diesem Ordner auslesen und ein SVG-Sheet erzeugen. Das Endergebnis ist stets reproduzierbar, weshalb wir es nicht versionieren möchten. Wir wählen beispielsweise den Ordner dist/assets/icons als Zielordner (alles unter dist ist unserem Falle von der Versionierung ausgenommen).

Mit Hilfe der Bibliothek shx können wir plattformunabhängig über ein NPM-Skript Shell-Befehle ausführen und unseren Zielordner erstellen, falls er noch nicht existiert. Mit npm install –save-dev shx fügen wir diese Abhängigkeit über NPM hinzu. Die Erzeugung des Ordners können wir dann über shx mkdir -p dist/assets durchführen.

Zum Erzeugen des SVG-Sheets nutzen wir die Bibliothek svgstore, bzw. deren Kommandozeilen-Pendant svgstore-cli. Dem Aufruf übergeben wir sowohl das Quellverzeichnis mit den Einzel-SVGs als auch das Zielverzeichnis für das Sheet. Weiterhin können wir ein Präfix für die Abbildung von Dateinamen auf ID vorsehen (alle IDs beginnen mit Icon.).

svgstore assets/icons/*.svg -o dist/assets/icons.svg -p Icon.

Nun haben wir im Grunde genommen schon das nutzbare SVG-Sheet. Wir optimieren noch etwas weiter, entfernen nicht benötigte SVG-Elemente oder führen potentiell andere Transformierungen durch, indem wir das Sheet über die Bibliothek svgo verarbeiten. Code-Beispiel 8 zeigt die verwendete Konfiguration, bei der wir nicht notwendige SVG-Gruppen und -Elemente entfernen, sowie das Ergebnis menschenlesbar formatieren.

Diese drei Automatisierungsschritte können wir jetzt in einzelne NPM-Skripte packen und sie z.B. vor jedem Bau unserer Webapplikation ausführen lassen (Code-Beispiel 9). Wir nutzen dabei NPM pre- und post-Hooks, die durch Namenskonvention vor- oder nachgelagert werden.

Der Code für das gesamte Beispielprojekt ist auf GitHub zu finden. Dort findet sich auch eine kleine Performance-Messung, deren Ergebnis auf Abbildungen 6 und 7 dargestellt ist: Wie eingangs erwähnt, ist zu erkennen, dass die Lade-Performance des großen SVG-Sheets deutlich besser ist als das Laden vieler, einzelner SVGs. Es kommt hierbei zu keinem Nachladen der Einzel-Grafiken. Der zuvor angesprochene Flimmer-Effekt bei modalen Dialogen tritt hierbei nicht auf. Das liegt u.a. daran, dass der Browser das Sheet zwischenspeichert und die Auswahl weiterer IDs kein Neuladen provoziert. Die Icons sind direkt verfügbar. Noch einen Schritt weiter kann man gehen, indem man initial, unabhängig von der Verwendung eines ersten Icons, das Sheet bereits einmal vorlädt (z.B. direkt beim Laden der Einstiegsseite index.html).

 

SVG-Sheets: Komfortables Tooling zur Verwaltung von Icons im modernen Web – Fazit

Mit dem Einsatz von Icon-Fonts kann man im Web bereits recht gut Vektorgrafiken im SVG-Format verwenden. Die damit einhergehenden Nachteile, allen voran der ungünstig in ein größeres Projekt integrierbare manuelle Ablauf zur Erstellung eines Fonts, haben mich immer wieder dazu gebracht, Alternativen zu erforschen.

Der vorgestellte, automatisierbare Workflow lässt sich in vielen modernen Web-Projekte umsetzen. Erweiterungen des Prozesses bieten darüber hinaus noch mehr Potential: Zweifarbige Icons mit einstellbarer Vorder- und Hintergrundfarbe kann man beispielsweise umsetzen, indem man fest benannte Teilbereiche in seinen SVGs adressiert. Denkbar ist auch eine Kategorisierung und Beschreibung der Icons auf fachlicher Ebene über HTML-Metadaten, die zusätzlich automatisiert verarbeitet werden können. Dies kann Entwicklern/-innen helfen, Icons für ein bestimmtes Einsatzgebiet in einem Sheet zu finden.

Zu guter Letzt lassen sich um die Nutzung der SVG-Primitiven herum mit Frameworks wie Angular, Vue oder React spezielle Icon-Komponenten entwickeln, die Implementierungsdetails verbergen. Der/die Entwickler/-in im Projekt muss nur die ID eines Icons kennen, folgende Zeile schreiben und bekommt so alle Vorteile aus den im Artikel vorgestellten Techniken geschenkt:

<my-icon key=”Login” color=”blue” size=”42” />

Quellen und weitere nützliche Referenzen

David Würfel

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Die von Ihnen hier erhobenen Daten werden von der Host Europe GmbH zur Veröffentlichung Ihres Beitrags in diesem Blog verarbeitet. Weitere Informationen entnehmen Sie bitte folgendem Link: www.hosteurope.de/AGB/Datenschutzerklaerung/