Im Adventkalender ging es am 10. Tag um das Thema „Eigene Social Sharing Buttons ohne Plugin umsetzen„. Darin habe ich unter anderem erwähnt, wie man die Bilder per Data-URL einbinden kann, damit der Browser keine zusätzlichen Requests durchführen muss. Heute möchte ich das Thema nochmals aufgreifen und euch zeigen, wie ihr mit Hilfe von Less oder Compass das Ganze noch viel schneller erreichen könnt.
Der manuelle Weg
Schauen wir noch einmal auf den Weg, den ich im vorherigen Artikel beschrieben habe. Dort wurde empfohlen, den Quellcode der SVG-Datei in einen Online-Dienst zu kopieren (für Bilder in einem Pixelgrafik-Format gibt es ebenfalls passende Dienste). Aber das Verfahren ist doch recht aufwändig. Bei jeder Änderung des Bildes muss man diesen Vorgang wiederholen. Nutzt man sehr viele Bilder, kann das schon mal viel Zeit kosten. Daher zeige ich euch nun, wie man es automatisieren kann.
Automatische Umwandlung mit CSS-Präprozessoren
Wer meinem Blog schon etwas länger verfolgt wird bestimmt den ein oder anderen Artikel zum Thema SASS gelesen haben. Wer mit diesem Begriff noch nichts anfangen kann, dem kann ich meinen Vortrag vom WordCamp Köln ans Herz legen bzw. das passende Video dazu.
Less
Neben SASS gibt es noch weitere CSS-Präprozessoren. Die bekannteste Alternative ist wohl Less. Diese verwende ich in manchen bestehenden Projekten ebenfalls und möchte euch daher auch hierfür die Funktion vorstellen. Alles was ihr angeben müsst ist folgendes (gleiches Beispiel wie im vorherigen Artikel):
.social-icons a.facebook { background-image: data-uri('../images/facebook.svg'); }
Ihr müsst also lediglich die Funktion data-uri()
anstelle von url()
verwenden und Less kümmert sich um den Rest. Das Ergebnis sieht dann wie folgt aus:
.social-icons a.facebook { background-image: url("data:image/svg+xml,%3Csvg%20width%3D%221792%22%20height%3D%221792%22%20viewBox%3D%220%200%201792%201792%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M1343%2012v264h-157q-86%200-116%2036t-30%20108v189h293l-39%20296h-254v759h-306v-759h-255v-296h255v-218q0-186%20104-288.5t277-102.5q147%200%20228%2012z%22%2F%3E%3C%2Fsvg%3E"); }
Wenn ihr genauer hinseht, dann werdet ihr feststellen, dass Less keine Base64-Kodierung verwendet. Das ist im Fall eines SVG auch nicht wirklich notwendig, da es sich ja um eine Textdatei handelt. Anders würde es aussehen, wenn wir stattdessen ein PNG verwenden:
.social-icons a.facebook { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAA1ElEQVRYhe2VsQrCMBBAH+pQcHN18ycUwcmv6OA/+AFuru7OfoKLk38hbqLgUgfR7oK6RCj2KOHa2MF7cEPC5e6FJC0Y5WgCE2ALXIEXcAfOwC508wjYuKZSPEILLAuaBxfougalBVpKgbGwNgUWwAF4OolgzMjveKop1FAKtIW5/S8FJFSXrkoBFb6XcAQMM+OBkBMD/cz4AqyUXjnmFD85KdY+hUMewenvBY5VFusAvUxI/4H4KyfyKez7Cm4uPqRCToJi17V/B0zABEzABGoXMIw3J6JHbpLPTjQAAAAASUVORK5CYII="); }
Da ein PNG eine Binärdatei ist, muss eine Kodierung wie Base64 zum Einsatz kommen. Ihr könnt im Falle von SVG aber auch die Kodierung als Base64-String erzwingen, indem ihr zwei Parameter verwendet:
.social-icons a.facebook { background-image: data-uri('image/svg+xml;base64', '../images/facebook.svg'); }
Weitere Beispiele findet ihr in der Less-Dokumentation zu der Funktion.
Compass
Bei neuen Projekte arbeite ich eigentlich immer mit SASS. Eine ähnliche Funktion wie bei Less gehört allerdings nicht zum normalen Funktionsumfang von SASS. Die sehr beliebte SASS-Erweiterung Compass bietet aber eine solche Funktion an. Man verwendet sie wie folgt:
.social-icons a.facebook { background-image: inline-image('../images/facebook.svg'); }
Auch hierbei wird das Bild automatisch kodiert und im Gegensatz zu Less wird hierbei auch immer die Base64-Kodierung angewendet, selbst bei einem Bild im SVG-Format:
.social-icons a.facebook { background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMzQzIDEydjI2NGgtMTU3cS04NiAwLTExNiAzNnQtMzAgMTA4djE4OWgyOTNsLTM5IDI5NmgtMjU0djc1OWgtMzA2di03NTloLTI1NXYtMjk2aDI1NXYtMjE4cTAtMTg2IDEwNC0yODguNXQyNzctMTAyLjVxMTQ3IDAgMjI4IDEyeiIvPjwvc3ZnPg=='); }
Wie ihr in der Dokumentation nachlesen könnt ist es auch bei Compass möglich, einen MIME-Type anzugeben, allerdings wird hierfür im Gegensatz zu Less der zweite Parameter verwendet.
Bonustipp: Web Fonts einbinden
Nicht nur Bilder können eingebunden werden. Auch bei der Verwendung von Web Fonts kann eine Data-URL eingesetzt werden. Während die data-uri()
Funktion von Less auch hierbei verwendet werden kann, muss bei Compass die Funktion inline-font-files()
eingesetzt werden.
Fazit
Die Verwendung eines CSS-Präprozessors kann einem Entwickler die Arbeit in vielerlei Hinsicht erheblich erleichtern. Wenn man im CSS-Code Data-URLs verwenden möchte, dann sollte man sich die hier vorgestellten Funktionen auf jeden Fall merken und zukünftig verwenden. Ich bin auch erst vor ein paar Wochen darauf gestoßen und überarbeite nun alle meine Projekte, damit ich noch schneller auf Änderungen reagieren kann, ohne jedes Mal manuell die Umwandlung vornehmen zu müssen.
Ein kleiner Zusatz zu SVG-Dateien:
SVGs in base64-Encodierung resultieren in ~30% mehr Größe im Vergleich zur Original-SVG.
Bei SVG-Dateien reicht die Umwandlung als HTML-Codierung (muss nicht, aber die Kompatibilität ist höher) und das direkte Einfügen, damit bleibt die Dateigröße kleiner als bei der bas64-Encodierung.
Mehr dazu gibt’s auch unter https://css-tricks.com/probably-dont-base64-svg/
Interessanter Hinweis, danke. Aber anscheinend sind es nicht immer 30% mehr. Ich war zuerst auch skeptisch, ob der Base64-String länger ist, aber in dem von mir verwendeten Beispiel sind beide Strings exakt gleich lang (350 Zeichen). Ist vielleicht Zufall, aber generell kann man wohl nicht davon ausgehen, dass es bei SVG immer zu einer größeren Dateigröße kommt.
Ich denke die Ersparnis im Artikel rührt daher, dass die „HTML-Special-Chars“ nicht URL-encoded wurden. Einige Browser scheinen aber das URL-Encoding zu benötigen (wie in den Kommentaren angemerkt). Ich würde im Zweifel darauf vertrauen, dass Less und Compass wissen, wie sie die Umwandlung durchführen müssen. Wenn man nicht gerade dutzende Bilder verwendet, sollte der Unterschied auch nicht so sehr ins Gewicht fallen.
Der Unterschied ist wie von dir erwähnt ja auch nicht dramatisch – man bewegt sich da mehr in Byte-Größen als in Kilobyte.