SVG-Icons statt Icon-Font im neuen Default Theme

Vorgestern hatte ich euch ja einige Neuerungen von WordPress 4.7 vorgestellt. Eine weitere Neuerung betrifft ein Detail des neuen Default Theme TwentySeventeen. Bisher wurden für Icons immer sogenannte Icons-Fonts verwendet. Also Schriftarten, die nur Icons enthalten.

Nachteile von Icon Fonts

In meinen Folien zum Vortrag beim WordCamp Nürnberg 2016 hatte ich euch ja schon berichtet, weshalb Icons-Fonts gegenüber SVG Dateien viele Nachteile haben. Hier noch einmal die Übersicht:

Icon Font SVG
Rendering May be anti-aliased Just “as is”
CSS Control Only text styles usable CSS font properties + SVG-specific CSS
Positioning Hard, due to line-height, vertical-align, letter-spacing, word-spacing Easy, it‘s just an ordinary image
Loading Issues CORS headers, Content-Type, broken CDN Just hosted as a regular image
Other Issues Proxy browsers (Opera Mini), User overwrites fonts, blocking of custom fonts No issue even with proxy browsers
Semantics Pseudo-Elements, <span>, <i>, this is bad An image is an image
Accessibility Text might be tried to read by screen reader Attributes like title, desc, aria-labelledby
Ease of use Not very easy to create custom font Have I mentioned, they are images? J
Browser Support Even in IE6 Not in IE 8 and Android 2.3

Einbindung von SVG in TwentySeventeen

Statt also eine Icon-Font zu verwenden, setzt TwentySeventeen als erstes Default Theme auf SVG Dateien. Die optimale Einbindung davon wird über <use> Tags gelöst. Dazu ist jedes Icon in der SVG-Icons-Datei in einen <symbol> Tag eingebettet. Über die ID des jeweiligen Tags kann dieser dann verwendet werden. Ein solches Symbol sieht z.B. wie folgt aus:

<symbol id="icon-next" viewBox="0 0 32 32">
	<path class="path1" d="M16 9.292l-1.354 1.354 5.354 5.354h-14v2h14l-5.354 5.354 1.354 1.354 7.708-7.708z"></path>
</symbol>

Um dieses Icon nun zu verwenden, definieren wir an der entsprechenden Stelle einen <use> Tag, der angibt, welches Icon verwendet werden soll:

<svg class="icon icon-next" aria-hidden="true" role="img">
	<use href="#icon-next" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-next"></use>
</svg>

Über das xlink:href Attribut wird also angegeben, das Symbol mit welcher ID verwendet werden soll. Interessant ist hier auch der umgebende <svg> Tag. Dieser verwendet das aria-hidden Attribut. Was es damit auf sich hat, habe ich euch ja bereits am 4. Dezember erklärt.

Einfache Verwendung von Icons in TwentySeventeen

Ein solches SVG einzubinden ist natürlich sehr viel aufwändiger als bei einem einfachen Bild. Daher wurde bei der Entwicklung von TwentySeventeen die Hilfsfunktion twentyseventeen_get_svg() implementiert, der den SVG-Code zum entsprechenden Icons generiert. Um das Icon wie oben zu erhalten, verwendet man folgenden Funktionsaufruf:

echo twentyseventeen_get_svg( array( 'icon' => 'next' ) );

Der Parameter der Funktion ist ein Array mit den Optionen zur Ausgabe des Bildes. Hierbei muss nur zwingend der Name des Icons angegeben werden, dass man verwenden möchte. Über weitere Optionen kann man aber Beispielsweise Title und Desc, das aria-hidden Attribut oder einen Fallback steuern.

Solltet ihr also mit dem Gedanken spielen, ein Child-Theme für TwentySeventeen zu erstellen, dann merkt euch diese Funktion, denn sie nimmt euch viel Arbeit ab und ermöglicht euch die optimale Einbindung von SVG-Icons.

Fazit

Ich hoffe ich konnte euch zeigen, dass es sich immer lohnt, bei einem neuen Default Theme auch mal in den Code zu sehen, um neue Funktionen und Lösungen zu entdecken. Falls ihr selbst Themes entwickelt, dann würde ich euch empfehlen, ebenfalls eine solche Funktion bereitzustellen.

Falls ihr euch aber fragt, wie man eine solche SVG-Datei, die alle Icons als Symbole enthält, am besten erstellen kann, dann habe ich hierzu in den nächsten Tagen einen weiteren Artikel für euch 🙂

Veröffentlicht von

Bernhard ist fest angestellter Webentwickler, entwickelt in seiner Freizeit Plugins, schreibt in seinem Blog über WordPress und andere Themen, treibt sich gerne bei den WP Meetups in Berlin und Potsdam herum und läuft nach Feierabend den ein oder anderen Halbmarathon.

8 Kommentare » Schreibe einen Kommentar

  1. Grundsätzlich bin ich voll bei dir, dass SVG wesentliche Vorteile gegenüber einer Schrift hat.

    Ein Problem jedoch bei der Nutzung von xlink:use ist, dass es nicht über ::before und ::after genutzt werden kann. Dadurch stehen eine Vielzahl von Gestaltungsmöglichkeiten nicht zur Verfügung, da man sich mittlerweile daran gewöhnt hat, Icons über diese Pseudo-Elemente einzubinden.

    • Danke für deinen Kommentar Matthias. Ich kann verstehen, dass eine Umstellung immer etwas unangenehmes ist. Aber gerade die Verwendung von Icons über die Pseudoelemente macht ja die Gestaltung unflexibel (oder zumindest sehr viel schwerer). Wenn das SVG Icon ein echter Tag mit einer CSS-Klasse ist, kann man alle Bereiche davon per CSS anpassen (also alle Pfade, Füllfarben, etc.). Als Hintergrundbild in einem Pseudoelemente hat man diese Möglichkeiten nicht.

      • Als Beispiel kann ich noch “Listen” anbringen: Wenn man z.B. möchte, dass <li>-Elemente ein spezielles Icon vorangestellt bekommen, kommt man um ::before nicht herum, außer man fügt ein <img>-Element pro Listenelement hinzu. Oder gibt es da eine andere Möglichkeit?

        • Auch das ist möglich. Ich weiß zwar nicht, ob es mit einem eingebundenen SVG funktioniert, auf jeden Fall aber mit einem externen SVG:

          li::before {
          	background-image: url(icons.svg#icon-next);
          }
          
  2. Hi Bernhard,
    vielen Dank für den Artikel. Das Einzige, was mich derzeit an der SVG-Einbindung in Twentyseventeen stört ist, dass die Definitionen immer über wp_footer eingebunden werden. Das sind ja immer ca. 50kB pro Seite. Auch auf Seiten, wo evtl. kein einziges Symbol verwendet wird (okay, eher unwahrscheinlich). Ich selbst habe bisher noch nicht viel mit SVG gemacht, hier und da mal eingebunden, aber jetzt noch nicht tiefer rein. Gibt es keinen browserübergreifenden Weg die SVGs als externe Ressource einzubinden, die – nachdem sie einmal geladen wurde – dann nicht ständig mitgeladen werden muss. Das würde ja doch unter Umständen ein paar KB/Pageload sparen.

    • Hallo David,

      es ist ohne weitere möglich die gleiche Datei als externe Ressource einzubinden. Bei der Betrachtung der Performance muss man immer absagen, ob ein zusätzlicher Request oder aber eine etwa größere HTML Datei besser ist. Bei 50kB würde ich es wohl auch so machen. Denn eine HTML Datei wird ja komprimiert übertragen (GZIP oder DEFLATE) und dann sind es eher nur 5-10kB.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert