Kürzlich bin ich im Rahmen eines kleinen Mobile-/Frontend-Workshops mit einem unserer Kunden auf eine interessante Fragestellung gestoßen: Kann man SVGs auch in Sprites verwenden?
Da ich die Antwort schlichtweg nicht wusste, habe ich es heute ausprobiert und dokumentiere hier das Ergebnis.
Warum SVGs?
SVGs lassen sich bekanntermaßen beliebig und verlustfrei skalieren. Das ist besonders für responsive Websites von großem Vorteil, da man hier oftmals keine feste Icon-/Bildgröße hat und sich die Bilder in den Fluss der Website einfügen sollen.
Da ich gerade schon von Icongröße geschrieben habe: Icons sind durch ihre Klar- und Einfachheit wie dafür geschaffen als SVG/Vektorgrafik eingebunden zu werden. Hier kommt oft folgendes „Gegenargument“ ins Spiel: Warum nicht einfach einen Icon-Font verwenden? Die Sinnhaftigkeit dieses Arguments hängt natürlich vom jeweiligen Projekt ab. Aber da oft nur ein Bruchteil der zur Verfügung stehenden Icons aus einem Font verwendet werden, lädt man bei Verwendung des gesamten Fonts einfach mehr Daten als nötig. Und das ist gerade für mobile Anwendungen und den Ansatz „Mobile First“ ein eindeutiges Argument gegen die Verwendung eines kompletten Icon-Fonts.
Ein zweiter Grund, warum die Verwendung von SVGs von Vorteil sein kann ist, dass die SVGs per CSS manipuliert werden können. Der Entwickler kann Farbe, Größe, Position, … des SVG beliebig verändern und ist dabei nicht mehr durch Dinge wie beispielsweise die line-height eines Icon-Fonts gebunden. Darüber hinaus können – je nach SVG und der Art, wie es eingebunden wird – auch einzelne Teile des SVG per CSS oder gar JavaScript beeinflusst werden. Doch dazu vielleicht in einem separaten Blog-Post mehr …
Es gibt also ausreichend gute Gründe, sich mit dem Einsatz von SVGs und den damit einhergehenden Möglichkeiten zu beschäftigen.
Warum Sprites?
CSS-Sprites nutzt man in der Webentwicklung schon seit Jahren, um große Teile der „Bilderwelt“ einer Website über nur einen einzigen, statt über viele kleine Requests zu laden. Man spart also unnötigen Overhead durch zu viele Requests, muss mit weniger konkurrierenden Requests umgehen (Browser/Server können nur eine gewisse Anzahl von Requests gleichzeitig bearbeiten) und hat durch das Zusammenfassen aller Icons/Bilder in eine gemeinsame Grafik oft kleinere resultierende Bildgrößen.
Weitere Informationen zu CSS-Sprites finden sich überall im Web, aber empfohlen seien hier einmal der Artikel auf CSS-Tricks und A List Apart.
Das Experiment
Um zu testen, ob sich SVGs auch über Sprites einbinden lassen, habe ich ein kleines Test-Projekt mit folgenden Rahmenbedingungen gestartet:
- Icons: der kürzlich releaste Octicons-Iconfont von GitHub
- Spriting: Compass-Spriting (Compass ist eine Erweiterung des CSS-Präprozessors SASS)
Der Octicon-Iconfont hat je nach Format eine Größe von 18 KB bis 85 KB. Dazu kommen dann noch – je nach Vorliebe des Entwicklers – das CSS oder SASS File mit jeweils 12 KB.
Extrahiert man nun aus dem Font drei exemplarische SVGs, erhält man SVG-Grafiken mit einer Größe von jeweils zwischen 1,2 KB und 1,9 KB. Extrahieren bedeutet in diesem Fall, dass der Font auf dem System installiert wird und z.B. in Illustrator über die Zeichentabelle einzelne Zeichen geöffnet, in Pfade umgewandelt und dann als .svg gespeichert werden.
Verwendet man also nur diese drei Icons aus dem Font, würde man beispielsweise gut 7 KB gegenüber dem kleinsten Format des Icon-Font einsparen. Das entsprechende CSS muss man natürlich selbst schreiben. Und dazu kommen wir jetzt.
Wie schon in der Headline angedeutet, möchte ich mit dem CSS-Framework Compass arbeiten, das auf dem CSS-Präprozessor SASS aufbaut. Compass bietet nämlich ein sehr komfortables Sprite-Handling, das ich eben auch gerne für SVGs nutzen wollen würde.
Zunächst habe ich ein test-svg.scss angelegt, dass folgende Zeilen enthält:
@import "compass/utilities/sprites"; @import "svg/*.svg";
In der ersten Zeile wird das Compass-Modul zum Erzeugen von Sprites importiert, in der Zeile darunter wird festgelegt, welche Dateien alle im Sprite zusammengezogen werden sollen. In diesem Fall wären das alle .svg-Dateien im Verzeichnis svg, das im konfigurierten images_dir von SASS liegt. Ruft man über die Konsole nun compass watch auf, erhält man folgende Ausgabe:
Change detected at 13:36:37 to: svg-test.scss error scss/svg-test.scss (Line 2: File to import not found or unreadable: svg/*.svg. Load paths: /var/www/scss /home/vagrant/.rvm/gems/ruby-2.1.2/gems/compass-0.12.6/frameworks/blueprint/stylesheets /home/vagrant/.rvm/gems/ruby-2.1.2/gems/compass-0.12.6/frameworks/compass/stylesheets Compass::SpriteImporter) overwrite css/svg-test.css
Ändert man in test-svg.scss die zweite Zeile wie folgt
@import "svg/*.png";
funktioniert der watch-Job korrekt und ein Sprite wird angelegt (vorausgesetzt man hat natürlich auch mindestens eine .png-Datei in das entsprechende Verzeichnis gelegt).
Change detected at 13:36:46 to: svg-test.scss create images/svg-s92150810c4.png overwrite css/svg-test.css
Damit ist bewiesen, dass man mit Compass keine SVG-Sprites erzeugen kann.
Hätte ich allerdings etwas früher etwas besser nachgedacht und mich umfassender an den Talk von Chris Coyier auf der btconf2014 erinnert, wäre mir vielleicht schon früher eingefallen, dass SVG-Files selbst mehrere SVG-Definitionen enthalten können und damit ein SVG-File auch ein Sprite-File sein kann.
Also lautet das eigentliche Fazit:
SVG-Sprites sind natürlich möglich, leider muss man diese aber manuell erzeugen bzw. kann sie nicht komfortabel über Compass bauen lassen.
Ich habe mich aktuell noch nicht schlau gemacht, ob es (andere) Tools gibt, die einem das Erzeugen von SVG-Sprites abnehmen / es vereinfachen. Hat jemand hier vielleicht einen Tipp / Link / Vorschlag?? …würde mich sehr interessieren!
(Zur Verwendung von SVGs allgemein ist in jedem Fall auch Herrn Coyiers SVG-Einführung auf CSS-Tricks sehr lesenswert!)
Schreibe einen Kommentar