Problem mit repeating-conic-gradient in einem SVG-Symbol
- svg
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
Guten Morgen,
foreignObject in symbol schien 2021 nicht in Chrome zu funktionieren[1]. Weiter unten gibt es einen Link zum W3C:
<foreignObject> and svg:use #511
The SVG Working Group just discussed <foreignObject> and svg:use, and agreed to the following:
RESOLVED: <foreignObject> in referenced subtrees of the <use> element would not be considered for the shadow tree
foreignObject in einem SVG-Standalone-Dokument (in img eingebunden) funktioniert, aber eben nicht in einem HTML-Dokument, das ein inline-SVG hat, dass dann mit foreignObejctwieder HTML enthält.
Warum das clipPath in symbol nicht funktioniert, kann ich auf die Schnelle nicht herausfinden.
Herzliche Grüße
Matthias Scharwies
SVG foreignObject inside symbol not showing in Chrome (Stackoverflow.com) ↩︎