Thomas Gigold hat sich unlängst in den Kaninchenbau von .svg-Grafiken gewagt und heute darüber berichtet. Da ich für dieses kleines Projekt von ihm auch zwei SVGs beigesteuert habe und ich sie auch hier im Blog nutze, möchte ich die Gelegenheit nutzen und von einer, für mich sehr interessanten, Möglichkeit schreiben, wie man mit nur einer SVG mehrere Grafiken zur Verfügung stellt. Die Rede ist von sogenannten SVG Stacks. Hier also mein Versuch zu erläutern, wie ich die Icons unter meinen Posts auf der Startseite mit eben solchen Stacks darstelle.

In SVG Stacks werden mehrere .svg-Grafiken in einer Datei "gestapelt". Aber kurz zur Erklärung, was eine SVG (Scalable Vector Graphic) eigentlich ist: Es handelt sich dabei um nichts anderes als ein XML-Dokument. Meine gestackten Icons unter den Beiträgen der Startseite sehen im Quelltext so aus:

<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<!-- https://icones.js.org/collection/hugeicons -->
    <defs>
        <style>
            g {
                display:none;
            }
            g:target {
                display:inline;
            }
        </style>
    </defs>

    <g id="commentmail">
        <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M6.099 19q-1.949-.192-2.927-1.172C2 16.657 2 14.771 2 11v-.5c0-3.771 0-5.657 1.172-6.828S6.229 2.5 10 2.5h4c3.771 0 5.657 0 6.828 1.172S22 6.729 22 10.5v.5c0 3.771 0 5.657-1.172 6.828S17.771 19 14 19c-.56.012-1.007.055-1.445.155c-1.199.276-2.309.89-3.405 1.424c-1.563.762-2.344 1.143-2.834.786c-.938-.698-.021-2.863.184-3.865" color="currentColor"></path>
    </g>
    <g id="permalink">
        <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m9.5 14.5l5-5m2.346 5.11l2.61-2.61A5.272 5.272 0 1 0 12 4.544l-2.61 2.61m5.22 9.692L12 19.456A5.272 5.272 0 1 1 4.544 12l2.61-2.61" color="currentColor"></path>
    </g>
    <g id="share">
        <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M18 7c.774.16 1.359.429 1.828.876C21 8.992 21 10.788 21 14.38s0 5.388-1.172 6.504S16.771 22 13 22h-2c-3.771 0-5.657 0-6.828-1.116S3 17.972 3 14.38s0-5.388 1.172-6.504C4.642 7.429 5.226 7.16 6 7m6.025-5L12 14m.025-12a.7.7 0 0 0-.472.175C10.647 2.94 9 4.929 9 4.929M12.025 2a.7.7 0 0 1 .422.174C13.353 2.94 15 4.93 15 4.93" color="currentColor"></path>
    </g>
    <g id="settings" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" color="currentColor">
        <path d="M15.5 12a3.5 3.5 0 1 1-7 0a3.5 3.5 0 0 1 7 0"></path>
        <path d="M20.79 9.152C21.598 10.542 22 11.237 22 12s-.403 1.458-1.21 2.848l-1.923 3.316c-.803 1.384-1.205 2.076-1.865 2.456s-1.462.38-3.065.38h-3.874c-1.603 0-2.405 0-3.065-.38s-1.062-1.072-1.865-2.456L3.21 14.848C2.403 13.458 2 12.763 2 12s.403-1.458 1.21-2.848l1.923-3.316C5.936 4.452 6.338 3.76 6.998 3.38S8.46 3 10.063 3h3.874c1.603 0 2.405 0 3.065.38s1.062 1.072 1.865 2.456z"></path>
    </g>
    <g id="webmention">
        <path fill="currentColor" d="M13.835961566773426,21.932605742761826l-2.8093921961327886-8.589376140621832h-0.04659987055591512L8.217510506915259,21.932605742761826h-3.6906564148432923L0.1394662792603354,5.347585145596818h3.644523209657751l2.6229927139091282,11.28916864119822h0.04633320462998714l2.8787253368740644-8.58964280654776h3.4125905205818876l2.8319254668737033,8.728442420993275h0.04653320407443313l2.0239943777933953-8.722709103585824l-2.6363926766870094-0.005733317407451646l5.464984819486612-5.07945255707623l3.3909239141002385,5.085985872261467l-2.6853925405762764-0.0016666620370498972l-3.724789653362074,13.880628109366365H13.835961566773426z" />
    </g>
</svg>

Wie du siehst, habe ich mehrere Grafiken in einzelne <g>-Container gelegt, um die jeweiligen SVG-Elementen zu gruppieren. Diese Container haben eindeutige IDs, über die ich sie dann per Stylesheet ansprechen, aufrufen kann. In den <defs>, einem weiteren SVG Element, sind simple CSS-Angaben hinterlegt, welche dafür sorgen, dass die <g>-Container nur dann sichtbar sind, wenn sie direkt angesprochen werden.

Dieses Ansprechen erledige ich im Stylesheet meiner Webseite mittels der mask-Eigenschaft vom CSS. Hier sieht man auch schön, wie ich einen einzelnen <g>-Con Rainer anspreche, als Target setze. (von den fünf verwendeten Icons

 .timelineMeta__icon {
     display: inline-flex;
     width: 1rem;
     height: 1rem;
     background-color: currentcolor;
     color: var(--contrast);
     vertical-align: middle;

     &__comment {
         -webkit-mask: url("assets/svg/pftnhr-timeline-stack.svg#commentmail");
         mask: url("assets/svg/pftnhr-timeline-stack.svg#commentmail");
     }

     &__permalink {
         -webkit-mask: url("assets/svg/pftnhr-timeline-stack.svg#permalink");
         mask: url("assets/svg/pftnhr-timeline-stack.svg#permalink");
     }

     &__share {
         -webkit-mask: url("assets/svg/pftnhr-timeline-stack.svg#share");
         mask: url("assets/svg/pftnhr-timeline-stack.svg#share");
     }

    &__settings {
         -webkit-mask: url("assets/svg/pftnhr-timeline-stack.svg#settings");
         mask: url("assets/svg/pftnhr-timeline-stack.svg#settings");
    }

    &__webmention {
         -webkit-mask: url("assets/svg/pftnhr-timeline-stack.svg#webmention");
         mask: url("assets/svg/pftnhr-timeline-stack.svg#webmention");
    }
}

Eingefügt werden die Icons dann mittel <i>-Tag, wie das bspw. auch von Fontawesome bekannt sein dürfet. Mein fertiger HTML-Code sieht dann so aus:

<div class="timelineMeta">
     <span class="timelineMeta__kommentar">
         <a href="mailto:[...]" title="Kommentiere per E-Mail" data-tooltip="Kommentiere per E-Mail" role="button">
               <i class="timelineMeta__icon timelineMeta__icon__comment"></I>
         </a>
     </span>
     <span class="timelineMeta__permalink">
          <a href="https://pfh.ax/4qpvn" rel="shortlink" type="text/html" class="u-url" title="Link zur Kurz-URL" data-tooltip="Kurz-URL" data-placement="bottom" role="button">
               <i class="timelineMeta__icon timelineMeta__icon__permalink"></i>
          </a>
     </span>
     <span class="timelineMeta__share" style="display: flex;">
          <button class="timelineMeta__share__link" data-title="Jonathan Hard oder wie ich nochmal 25 Jahre jung bin" data-url="https://pftnhr.xyz/heute-abend-geht-s-auf-ei-20251025" title="Link zum Teilen des Artikels" data-tooltip="Teilen" data-placement="bottom">
               <i class="timelineMeta__icon timelineMeta__icon__share"></i>
          </button>
     </span>
</div>

Das ist in meinen Augen eine ressourcenschonende, sowie elegante Lösung für Icons, Buttons und andere UI-Elemente. Noch dazu macht es Dinge wie den Darkmode oder ein Ändern des Farbschemas einfach, da die Farbe der SVGs per Stylesheet gesetzt werden.

Kommentiere per E-Mail

Autor: Robert Pfotenhauer Veröffentlicht: 25. Oktober 2025 um 15:00:00 Uhr Abgelegt unter:Praktische Anwendung von .svg-Dateien als Buttons oder UI-Elemente mit Hilfe von Stacks Permalink: https://pftnhr.xyz/thomas-gigold-hat-sich-un-20251025 Kurz-URL: https://pfh.ax/fqc56