Zum Inhalt springen
ConvertOwl

SVG in CSS - ein background-image, das wirklich funktioniert

Eine SVG in ein Stylesheet zu kleben scheitert auf zwei bestimmte Arten, und beide sind lautlos. Maskierst du falsch, schneidet ein unkodiertes Rautenzeichen in einer Füllfarbe die URL ab, die Regel wird also fehlerfrei geparst und das Bild erscheint einfach nie. Nutzt du currentColor in deiner Grafik, hört es in dem Moment auf zu wirken, in dem sie eine data:-URI wird, denn die URI ist ein eigenes Dokument, von dem es nichts zu erben gibt. Dieses Werkzeug erledigt das Erste für dich und warnt dich vor dem Zweiten, und gibt dir eine background-image-Deklaration, die du unverändert einfügen kannst. Es nutzt die URL-kodierte Form statt Base64, die für SVG sowohl kleiner als auch besser komprimierbar ist. Alles läuft auf deinem Gerät, und die Datei wird bereinigt, bevor irgendetwas erzeugt wird.

So verwendest du dieses Tool

  1. SVG hineinziehen

    Ziehe eine Datei auf das Feld oben oder klicke zum Auswählen. Skripte, Ereignis-Handler und Verweise außerhalb des Dokuments werden entfernt, bevor irgendetwas erzeugt wird, und das Feld listet auf, was es herausgenommen hat.

  2. Die background-image-Regel kopieren

    Der erste Ausschnitt ist eine vollständige Deklaration mit bereits maskierter und korrekt gefasster data:-URI - füge sie direkt in eine Regel ein. Darunter steht eine Base64-Fassung für Verarbeitungsketten, die darauf bestehen, mit beiden Byte-Zählern.

  3. Die currentColor-Warnung beachten

    Nutzt deine Grafik currentColor, erscheint ein Hinweis, der erklärt, warum sie schwarz erscheinen wird, und bietet stattdessen einen mask-image-Ausschnitt an. Dieser färbt die Form in der Textfarbe des Elements, das nächstliegende funktionierende Äquivalent.

  4. Die nötigen Größenangaben ergänzen

    Ein background-image allein kachelt in der Eigengröße der Grafik. Ergänze background-size und background-repeat: no-repeat, um das zu steuern, oder nimm den mask-Ausschnitt, der beides bereits enthält.

Häufig gestellte Fragen

Welche Zeichen müssen maskiert werden?

Fünf, dazu Zeilenumbrüche. Das Prozentzeichen muss zuerst dran, sonst würde es die Maskierungen maskieren. Dann das Rautenzeichen, das sonst ein URL-Fragment beginnt und alles nach deiner ersten Hexadezimalfarbe abschneidet. Dann die spitzen Klammern, die aus einem HTML-Attribut ausbrechen, und das doppelte Anführungszeichen um den Wert.

Mein background-image erscheint einfach nicht. Warum?

Fast immer ein unmaskiertes Rautenzeichen. Eine Füllung mit #c33 in einer unmaskierten data:-URI beendet die URL an der Raute, der Browser fordert also ein abgeschnittenes Dokument an, bekommt nichts Brauchbares und zeigt nichts - ohne Konsolenfehler, denn für CSS war die Regel vollkommen gültig.

Warum funktioniert currentColor in einer data:-URI nicht?

Weil die data:-URI ein eigenes Dokument ist. currentColor löst sich gegen die berechnete color-Eigenschaft des Elements auf, in dem die SVG steckt, und eine als Bild geladene SVG hat kein solches Element - sie ist nicht Teil deines Seitenbaums. Es fällt auf den Ausgangswert zurück, und der ist Schwarz.

Was ist der mask-image-Umweg?

Du nutzt die SVG als Schablone statt als Bild. Setze background-color auf currentColor, damit das Element in der geerbten Textfarbe malt, und nutze dann mask-image mit deiner data:-URI, sodass nur die Form der Grafik durchscheint. Ergänze -webkit-mask-image daneben für Safari.

Sollte ich in CSS lieber Base64 nehmen?

Selten. Base64 macht dasselbe Bild im Stylesheet etwa ein Fünftel größer und komprimiert deutlich schlechter, weil es für gzip wie Rauschen aussieht. Es lohnt nur, wenn ein Build-Werkzeug oder ein CMS die prozentkodierte Form ablehnt - deshalb bietet diese Seite beide an.

Kann ich einfache Anführungszeichen um den url()-Wert setzen?

Bei dieser Ausgabe nicht, und das ist Absicht. Attributtrennzeichen in der SVG werden zu Apostrophen, damit sie nicht maskiert werden müssen, und daher kommt der größte Teil der Ersparnis. Damit ist das doppelte Anführungszeichen die einzig sichere Klammer - ein Apostroph würde den Wert vorzeitig beenden.

Funktioniert das in einer CSS-Custom-Property?

Ja. Weise den ganzen url("…")-Wert einer Custom Property zu und referenziere sie, wo du sie brauchst - eine saubere Art, eine lange data:-URI aus der Mitte einer Regel herauszuhalten. Custom Properties nehmen den Wert als Tokenfolge, die Maskierung hier ist also bereits korrekt.

Ab wann ist es zu groß für ein Stylesheet?

Etwa ab 4 KB SVG-Quelltext, dort warnt das Feld. Eine data:-URI im CSS wird von jedem Besucher geladen, der dieses Stylesheet abruft, ob die Regel je greift oder nicht, und lässt sich nicht getrennt cachen. Darunter schlägt sie meist eine zusätzliche Anfrage, darüber meist nicht.

Kann ich eine ganze Illustration ins Stylesheet legen?

Können ja, sollten wohl nicht. Illustrationen liegen bei zigtausend Bytes, und jedes davon lädt jeder herunter, der das Stylesheet abruft, unabhängig davon, ob die Regel je zutrifft. Symbole und kleine dekorative Formen sind das, wofür data:-URIs gedacht sind; alles mit echtem Detail gehört in eine eigene Datei.

Wird das eingebettete Bild gecacht?

Nur als Teil des Stylesheets, das es enthält, das ist der Tausch. Es gibt keinen eigenen Cache-Eintrag und keine eigene Anfrage, der erste Besuch ist also schneller, und jede spätere Änderung am Stylesheet lädt das Bild mit neu. Für ein Symbol auf jeder Seite ist das meist ein guter Deal.

Wird etwas an einen Server geschickt?

Nein. Die Maskierung läuft in deinem Browser, die Datei verlässt dein Gerät also nie, wird nie gespeichert und nie von uns gesehen. Es bedeutet auch, dass es nichts abzuwarten gibt - die Ausschnitte erscheinen, sobald die Datei gelesen ist.

Funktioniert etwas nicht? Fehler melden