Icons im SVG Format in HTML und (S)CSS einbinden

Icons fehlen seit Jahren auf kaum einer Website. Die Geister (Webdevs) scheiden sich allerdings erheblich darin, wie man passende findet und einbindet.

My way: für VSCode gibt es die Extension React Icons. Diese habe ich installiert. Wenn ich ein Icon benötige, verwende ich in VSCode die Tastenkombination CMD SHIFT P und klicke auf React Icons. Dann wähle ich entweder eine der Bibliotheken aus oder gebe mindestens 3 Buchstaben ins Suchfeld ein. Habe ich ein passendes Icon gefunden, gehe ich mit der Maus (bzw. dem Touchpad) darüber und klicke auf copy SVG.
Beispiel: ein Home Icon. Ich entscheide mich für AiOutlineHome.
Folgender Code ist in meiner Zwischenablage:

<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M946.5 505L560.1 118.8l-25.9-25.9a31.5 31.5 0 0 0-44.4 0L77.5 505a63.9 63.9 0 0 0-18.8 46c.4 35.2 29.7 63.3 64.9 63.3h42.5V940h691.8V614.3h43.4c17.1 0 33.2-6.7 45.3-18.8a63.6 63.6 0 0 0 18.7-45.3c0-17-6.7-33.1-18.8-45.2zM568 868H456V664h112v204zm217.9-325.7V868H632V640c0-22.1-17.9-40-40-40H432c-22.1 0-40 17.9-40 40v228H238.1V542.3h-96l370-369.7 23.1 23.1L882 542.3h-96.1z"></path></svg>

So sieht es aus:

Meistens will ich das Icon mit einem Text bzw. einem Link verbinden – da Webinhalte ja vermeintlich nicht gelesen, sondern „gescannt“ werden, hilft das ungemein – und sieht im besten Fall auch noch gut aus.
Also kann ich etwa folgendes schreiben:

<a href="/"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M946.5 505L560.1 118.8l-25.9-25.9a31.5 31.5 0 0 0-44.4 0L77.5 505a63.9 63.9 0 0 0-18.8 46c.4 35.2 29.7 63.3 64.9 63.3h42.5V940h691.8V614.3h43.4c17.1 0 33.2-6.7 45.3-18.8a63.6 63.6 0 0 0 18.7-45.3c0-17-6.7-33.1-18.8-45.2zM568 868H456V664h112v204zm217.9-325.7V868H632V640c0-22.1-17.9-40-40-40H432c-22.1 0-40 17.9-40 40v228H238.1V542.3h-96l370-369.7 23.1 23.1L882 542.3h-96.1z"></path></svg> Home</a>

Das sieht so aus:
Home
Zwischenbemerkung: natürlich könnte ich das auch anders machen und zwar indem ich eine neue Datei anlege, den SVG Code hinein kopiere und als home.svg abspeichere.
Dann wäre der Code übersichtlicher:

<a href="/"><img src="home.svg">Home</a>

Der Unterschied ist, dass im ersten Fall eine per CSS definierte Linkfarbe im Icon übernommen wird, im zweiten Fall bleibt das Icon schwarz.
Ändern könnte ich das leicht, in dem ich den Code in der Datei home.svg anpasse und zwar muss in das path Element das Attribut fill mit Raute und HEX Wert der gewünschten Farbe geschrieben werden.

<svg ...><path fill="#CCC" d="..."></path></svg>

Allerdings würde dann das Icon bei Mouseover nicht in der Hover-Farbe erscheinen. Machen wir es lieber mit CSS.

SVG als Hintergrundbild ins CSS einbinden

Überhaupt soll *aus Gründen* das Icon nicht ins HTML geschrieben, sondern per CSS als Hintergrundbild eingefügt werden.
Verwendet man die SVG Datei sieht das CSS so aus:

.home {
    color:#FF0000;
    padding-left:20px;
    background-image:url(home.svg);
    background-repeat:no-repeat;
    background-position: 0 0;
    transition:all .3s;
    border-bottom:1px solid #FF0000;
    text-decoration:none;
}

.home:hover {
    color:#CCCCCC;
    background-image:url(home-hover.svg);
    border-bottom:1px solid #CCCCCC;
}

Tatsächlich benötigt man dann zwei SVG Dateien, bei denen jeweils das Attribut <code>fill</code> mit den entsprechenden Werten gesetzt wurde. Nicht wirklich schön. Man will (soll) ja Requests vermeiden.
Schreiben wir also folgendes in das CSS:

.home {
    color:#FF0000;
    padding-left:20px;
    background-image:url('data:image/svg+xml;utf8,<svg ...><path fill="%23FF0000"... </path></svg>');
    background-repeat:no-repeat;
    background-position: 0 0;
    transition:all .3s;
    border-bottom:1px solid #FF0000;
    text-decoration:none;
}
.home:hover {
    color:#CCCCCC;
    background-image:url('data:image/svg+xml;utf8,<svg ...><path fill="%23CCCCCC"... </path></svg>');
    border-bottom:1px solid #CCCCCC;
}

Hier ist nun folgendes wichtig: das das Attribut fill im Element path.
Verwendet man einen HEX Wert (und nicht eine Angabe wie ‚red‘, ‚purple‘, ‚aqua‘ usw.) so muss die # konvertiert werden mit %23!
Man kann das Ganze nun mit Variablen schreiben.

SVG Grafiken als Hintergrundbilder mit CSS Variablen definieren

:root {
    --homeSVG: url('data:image/svg+xml;utf8,<svg ...><path fill="%23FF0000" ...></path></svg>');
    --homeSVGhover: url('data:image/svg+xml;utf8,<svg ...><path fill="%23CCCCCC" ...></path></svg>');
}
.home {
    color:#FF0000;
    padding-left:20px;
    background-image: var(--homeSVG);
    background-repeat:no-repeat;
    background-position: 0 0;
    transition:all .3s;
    border-bottom:1px solid #FF0000;
    text-decoration:none;
}
.home:hover {
    color:#CCCCCC;
    border-bottom:1px solid #CCCCCC;
    background-image: var(--homeSVGhover);
}

Oder man macht es mit SCSS.

SVG Grafiken als Hintergrundbilder mit SCSS Variablen definieren

Etwas tricky ist es, das fill korrekt zu befüllen. Es bedarf dazu einer Funktion:

$color: #FF0000;
$colorhover: #CCCCCC;
@function svg-color($functioncolor) {
    @return '%23' + str-slice('#{$functioncolor}', 2, -1)
}
.home {
    color:$color;
    padding-left:20px;
    background-image:url('data:image/svg+xml;utf8,<svg ...><path fill="#{svg-color($color)}"... </path></svg>');
    background-repeat:no-repeat;
    background-position: 0 0;
    transition:all .3s;
    border-bottom:1px solid $color;
    text-decoration:none;
}
.home:hover {
    color:$colorhover;
    border-bottom:1px solid $colorhover;
    background-image:url('data:image/svg+xml;utf8,<svg ...><path fill="#{svg-color($colorhover)}" ... </path></svg>');
}

Oder man definiert die Icons als Variablen, wobei die Klammern konvertiert werden müssen:

$color: #FF0000;
$colorhover: #CCCCCC;
@function svg-color($functioncolor) {
    @return '%23' + str-slice('#{$functioncolor}', 2, -1)
}
$home: '%3Csvg ...%3E%3Cpath fill="fill="#{svg-color($color)}" .../%3E%3C/svg%3E';
$homehover: '%3Csvg ...%3E%3Cpath fill="#{change-svg-color($colorhover)}" .../%3E%3C/svg%3E';
.home {
    color:$color1;
    padding-left:20px;
    background-image:url('data:image/svg+xml;utf8,#{$home}');
    background-repeat:no-repeat;
    background-position: 0 0;
    transition:all .3s;
    border-bottom:1px solid $color1;
    text-decoration:none;
}
.home:hover {
    color:$colorhover;
    background-image:url('data:image/svg+xml;utf8,#{$homehover}');
    border-bottom:1px solid $colorhover;
}

 

Links:
https://css-tricks.com/change-color-of-svg-on-hover/
https://adactio.com/journal/15075
https://stackoverflow.com/questions/25477819/scss-variable-in-background-image-with-svg-image-data-uri
https://stackoverflow.com/questions/25477819/scss-variable-in-background-image-with-svg-image-data-uri