Kaskadierende SVG-Füllfarbe

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Einst erzählte mir jemand, dass sein größtes Problem mit SVG-Icons darin besteht, dass sie nicht mit der Farbe des umgebenden Textes übereinstimmen. Tatsächlich war das für ihn ein so großes Problem, dass er trotz der Vorteile von SVG-Icons bei Icon-Schriften blieb. Ich habe damals nicht darüber nachgedacht, aber dafür gibt es eine ziemlich einfache Lösung.

Die Idee ist, den currentColor-Wert in CSS zu verwenden, um diese Textfarbe an die SVG-Formen weiterzugeben. Zum Beispiel

<h1>
  <svg viewBox="0 0 32 32">
    <use xlink:href="#icon-phone"></use>
  </svg>
  Call Me
</h1>
h1 {
  color: blue;
}
h1 svg {
  fill: currentColor;
}

Sie können dies vereinfachen und die Füllung auf das SVG kaskadieren lassen

h1 {
  color: blue;
  fill: currentColor;
}

Die Füllung kaskadiert also, na? Ziemlich schick. Warum machen wir das nicht einfach, wenn es so einfach ist?

body {
  fill: currentColor;
}

fill beeinflusst sowieso nur SVG, daher wird es nichts tun, was wir nicht wollen, und es kann leicht durch einen spezifischeren Selektor überschrieben werden.

Das Problem ist, dass das so noch nicht ganz funktioniert.

Nehmen Sie dieses Beispiel, das einfach unser ursprüngliches Beispiel innerhalb von <body> ist

<body>
<h1>
  <svg viewBox="0 0 32 32">
    <use xlink:href="#icon-phone"></use>
  </svg>
  You'd think the SVG would fill blue too?
</h1>
</body>

Dann

body {
  fill: currentColor;
  color: red;
}
h1 {
  color: blue;
}
svg {
  border: 5px solid currentColor;
}

Was ist die currentColor am <svg>? blau, richtig? Weil color kaskadiert (vererbt wird). Wir sehen, dass das stimmt, weil der Rand dieses SVGs blau sein wird. Aber das Icon selbst (das eigentlich ein gezeichnetes <path> ist) wird rot.

Merkwürdig, finde ich.

Update: Funktioniert (korrekt?) jetzt in Chrome. Firefox und Safari zeigen immer noch die seltsame rote Füllung.

Es ist aber keine riesige Sache, denn Sie können einfach

svg {
  fill: currentColor;
}

Und das stellt sicher, dass es die Farbe von dem nimmt, was man normalerweise erwarten würde. Sie können die Füllung auch auf das use, path, symbol, circle, rect usw. anwenden, aber wenn man das svg trifft, deckt es im Grunde alles ab (was für einfache einfarbige Anwendungsfälle schön ist).

Siehe den Pen lcDBd von Chris Coyier (@chriscoyier) auf CodePen.