Auge: Problem mit repeating-conic-gradient in einem SVG-Symbol

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):

Screenshot der Ausgabe der SVG-Grafik des Disk-Stapels. Links als einzelne Disk, in der Mitte der Disk-Stapel, beide in einem HTML-Dokument mit "use" eingebunden, rechts  die Einbindung als "img".

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
  1. 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


    1. SVG foreignObject inside symbol not showing in Chrome (Stackoverflow.com) ↩︎