#LR16: SVG-Icons und ein CSS-Hack
Unten in der zum Footer umfunktionierten Seitenleiste stehen Links zu den für mich „wichtigen“ Social-Media-Kanälen, und weil das in Textform ein wenig langweilig ist, sind es Icon-Links. Icons hat man früher™ mit Rastergrafiken umgesetzt (erst als GIF und dann meist als PNG), dann ist uns aufgefallen, dass wir dafür besser CSS-Sprites erzeugen sollten (weil dann nur eine Grafikdatei geladen werden muss) und als uns auffiel, dass das auf Dauer ganz schön umständlich ist, haben wir Iconfonts genutzt. Mittlerweile haben wir erkannt, dass auch das Problemchen mit sich bringt und verwenden Vektor-Grafiken, vorzugsweise in Form von SVG-Sprites.
SVG-Sprites to the rescue!
Die hier verwendeten sind von SocialCons und ursprünglich „ab Werk“ (ein)farbig, aber das müssen SVG-Icons nicht sein, denn man kann sie mit CSS – in gewissen Grenzen – einfärben. Das ist relativ flexibel: falls sich das Farbschema ändert oder Facebook morgen beschließt, dass sein blau irgendwie nicht mehr blau genug ist, ändert man einfach im CSS den Farbwert und gut. Die Icons im Iconsprite dieses Themes haben also gar keine Farbe, den Social-Icons weise ich stattdessen die Markenfarben mittels fill
zu, weil das ein bisschen mehr Farbe ins Theme bringt und auch irgendwie netter aussieht als nur weiße oder rote Icons.
Man sieht: Die sind zunächst mal nur einfarbig, was logisch ist – z.B. für das Twitter-Icon sieht der SCSS-Code schließlich so aus:
.icon-twitter {
fill: #55acee;
}
Ich weise also keinem „Unterelement“ im SVG eine weitere Farbe zu oder so.
Füllen & runden
Ich wollte aber möglichst, dass die Icons weiß „gefüllt“ sind, damit sie sich noch etwas besser abheben. Das sollte doch nicht schwer sein, man kann ja dem SVG-Element eine Hintergrundfarbe zuweisen, oder? Naja – der Inhalt der Icons enthält hier eine runde Form, die Icons per se (die <svg>
-Elemente) haben aber immer noch eine quadratische Box mit einer definierte Breite und Höhe von je 3rem
, wie man sieht.
Kein Problem, oder? Dank border-radius
können wir die berühmt-berüchtigten „runden Ecken“ ja mittlerweile in CSS erzeugen, und setzt man border-radius: 50%;
, ergibt das Kreise. Das verwende ich hier z.B. für Avatare in den Kommentaren oder für mein Foto im Autoreninfo weiter unten. Aber irgendwas läuft da bei den Social-Icons immer noch nicht, wie soll, ich sagen: rund.
Ich habe bislang nicht exakt bestimmen können, was da schief läuft, aber da die SVG-Icons nicht exakt gleich groß sind (29×29, 30×30 und 30×29), sind sie vielleicht auch einfach nicht exakt deckungsgleich? Dafür würde sprechen, dass der „Rand“ unterschiedlich ausgeprägt ist. Allerdings kann ich mir nicht vorstellen, wie man als Icondesigner dazu kommt – man verwendet doch immer die gleiche Vorlage?! Auch denkbar wären Rundungsfehler, da der border-radius
in Prozent angegeben ist. Oder beides.
Endlich mal wieder ein kruder CSS-Hack!
Nun sieht man aber in der Live-Version des Blogs derzeit keinen „Rand“. Die offensichtlich beste Lösung wäre, die Icons in einer „isolierten“ Version zu verwenden (die es bei diesem Set sogar gibt) und den Kreis samt Farbe komplett in CSS zu machen. Wahrscheinlich mache ich das auch noch, aber das dauert ein wenig, weil ich erst wieder die Icons zusammenstellen und optimieren müsste. Also musste eine Behelfslösung her, und die sieht so aus:
#social {
[class^="icon-"],
[class*="icon-"] {
background: linear-gradient($off-white, $off-white) 50% 50%/1.875rem 1.875rem
no-repeat;
border-radius: 50%;
}
}
Nachtrag: Wie Malte in den Kommentaren feststellte, funktioniert der ursprünglich Hack in Firefox nicht. Offenbar braucht Firefox im background
-Shorthand explizit beide Werte für Position und Größe, auch wenn diese gleich sind.
Ein richtig schöner, kruder CSS-Hack, wie wir ihn früher ständig benutzt haben. Die Idee war folgende: Man müsste die Größe des weiß gefüllten Hintergrunds unabhängig von der Größe des <svg>
-Elementes festlegen können. Im Prinzip gibt es dafür in CSS background-size
, aber das greift nur bei Hintergrundbildern. Aber, Moment – wir können ganz einfach über CSS etwas erzeugen, was technisch gesehen ein Hintergrundbild ist, nämlich einen linearen Gradienten.
Natürlich ist das oben komplett krude – es ist ein Verlauf von wollweiß zu wollweiß, der zentriert und ohne Wiederholung hinter einem SVG positioniert, auf 66,66% deren Größe verkleinert und mittels border-radius
beschnitten wird. Aber: Es funktioniert und skaliert.