Hallo
Ich versuche, alle meine SVG-Icons in einer SVG-Datei als Symbole (<symbol>) bereitzustellen. Alles funktioniert, mittlerweile auch mit Unterstützung für Light- und Dark-Modes per CSS-Variablen. Nur ein Icon macht ernsthafte Probleme.
Es besteht aus einem Stapel Discs und soll als Icon für Datenbankkram dienen. Es ist als ein Symbol, das dreimal mit <use> verwendet wird, aufgebaut und enthält als Deckplatte ein Element mit einem repeating-conic-gradient. SVG unterstützt konische Gradienten von sich aus leider nicht (was ich im Übrigen für ein Armutszeugnis halte). Laut einem Github-Issue, das mir vor ein paar Tagen vor die Nase kam, soll sich das erst mit SVG 2.1 ändern. Das ist dann also $irgendwann. Deshalb musste ich den Umweg über ein HTML-Element als Kind eines <foreignObject> nehmen. Da das Element ellypsenförmig ist, wird es zusätzlich mit einem <clipPath> zurechtgeschnitten.
Das Problem ist nun folgendes. Binde ich die SVG-Grafik mit <img> in einem HTML-Dokument ein, ist die Ausgabe fehlerfrei. Binde ich die Grafik hingegen mit <svg><use /></svg> ein, fehlt das Kindelement des `<foreignObject>.
Der Quelltext der SVG-Datei:
<svg id="icon-collection" xmlns="http://www.w3.org/2000/svg" xmlns:xhtml="http://www.w3.org/1999/xhtml" viewBox="0 0 264 264">
<defs>
<linearGradient id="dbase-cylinder-face" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#7f99b9" />
<stop offset="46%" stop-color="#a2bfdf" />
<stop offset="66%" stop-color="#bae8fa" />
<stop offset="86%" stop-color="#a4c6ed" />
<stop offset="100%" stop-color="#98bcde" />
</linearGradient>
<clipPath id="disc-top">
<path d="M 28 108 A 104 48 180 0 1 236 108 A 104 48 180 0 1 28 108 z" />
</clipPath>
<style>
.cover-plate {
width: 100%;
height: 100%;
background: repeating-conic-gradient(
from -90deg,
#8f9fbc 0deg,
#a2bfdf 25.2deg,
#bae8fa 60deg,
#a4c6ed 94.8deg,
#8f9fbc 180deg
);
</style>
<symbol id="disc">
<foreignObject x="0" y="60" width="264" height="100" clip-path="url(#disc-top)">
<xhtml:div class="cover-plate" />
</foreignObject>
<path class="front" d="M 28 108 A 104 48 180 0 0 236 108 l 0 40 A 104 48 180 0 1 28 148 z" fill="url(#dbase-cylinder-face)" stroke="none" />
<path class="frontcontour" d="M 28 108 A 104 48 180 0 0 236 108" fill="none" stroke="#9abfe4" stroke-width="5" stroke-linecap="round" />
<path class="contour" d="M 28 108 A 104 48 180 0 1 236 108 l 0 40 A 104 48 180 0 1 28 148 z" fill="none" stroke="#7894b2" stroke-width="5" />
</symbol>
</defs>
<!--symbol id="dbase"-->
<use href="#disc" viewBox="0 0 264 264" x="0" y="63" />
<use href="#disc" viewBox="0 0 264 264" x="0" y="3" />
<use href="#disc" viewBox="0 0 264 264" x="0" y="-57" />
<!--/symbol-->
</svg>
So sieht das Ergebnis aus (Screenshot von einer Testseite):
Links ist das Symbol für die einzelne Disk zu sehen, in der Mitte das aus drei Disks zusammengebaute Symbol. Beide Grafiken wurden mit <svg><use /></svg> in das HTML-Dokument eingebunden und die Deckplatte mit dem Gradienten fehlt. Rechts zum Vergleich die selbe Grafik, eingebunden mit <img> mitsamt angezeigter Deckplatte. So sieht das sowohl in einem aktuellen Firefox als auch in aktuellen Chromium-basierten Browsern aus.
Ich habe den Gradienten mal testweise weggelassen und das Element im <foreignObject> schlicht mit einer Farbe gefüllt und das funktioniert auch nicht. Kann mir jemand erklären, worin das Problem liegt? Kann man in einem Symbol keinen <clipPath> verwenden oder eventuell kein <foreignObject>?
Ich bin ratlos und finde partout nichts, was mein konkretes Problem behandlt. Vielleicht liegt es an meinen Suchbegriffen, aber das weiß ich halt nicht.
Tschö, Auge
„Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
