Heroicons, Phosphor und Inline-SVG richtig einsetzen
Icons sind in jedem UI omnipräsent – und werden trotzdem häufig falsch eingesetzt. Zu groß, falsche Farbe, nicht barrierefrei, als PNG statt SVG. Dieser Guide zeigt, wie man Heroicons, Phosphor Icons und Inline-SVG mit Tailwind CSS v4 korrekt und performant einsetzt.
Inhaltsverzeichnis
- 1. Warum SVG Icons und kein Icon-Font
- 2. Heroicons: die natürliche Wahl für Tailwind-Projekte
- 3. Phosphor Icons: Flexibilität durch mehrere Stile
- 4. Größe und Farbe mit Tailwind steuern
- 5. Barrierefreiheit: aria-hidden, aria-label und title
- 6. Inline-SVG: wann und wie
- 7. SVG-Sprites für skalierbare Icon-Systeme
- 8. Hover- und Übergangsanimationen auf Icons
- 9. Icon-Ansätze im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum SVG Icons und kein Icon-Font
Icon-Fonts wie Font Awesome waren lange Standard, haben aber strukturelle Nachteile, die mit dem modernen Frontend-Ansatz von Tailwind CSS nicht harmonieren. Icon-Fonts laden immer die gesamte Font-Datei, auch wenn nur fünf Icons genutzt werden. Sie skalieren nicht scharf auf allen Displaytypen (besonders Retina-Displays). Sie blockieren das Rendering, weil sie als Font geladen werden. Und sie sind schwerer zugänglich zu machen: Ein Icon-Font-Zeichen ist für Screen-Reader eine unbekannte Zeichensequenz, sofern nicht manuell mit aria-hidden und Beschriftungen nachgebessert wird.
SVG-Icons lösen alle diese Probleme. Als Inline-SVG direkt im HTML sind sie ohne externen Request verfügbar, skalieren verlustfrei auf jeden Pixel und können über Tailwind-Klassen wie w-5 h-5 text-sky-600 in Größe und Farbe gesteuert werden. Die Farbe eines Inline-SVG-Icons mit fill="currentColor" oder stroke="currentColor" erbt die CSS-color-Eigenschaft des übergeordneten Elements – Tailwinds text-{color}-Klassen wirken also direkt auf das Icon. Das macht Tailwind Icons zu einem vollständig im Utility-System integrierten Feature.
2. Heroicons: die natürliche Wahl für Tailwind-Projekte
Heroicons wurde von denselben Entwicklern erstellt wie Tailwind CSS (Adam Wathan, Steve Schoger) und ist deshalb namentlich und konzeptionell auf das Tailwind-Ökosystem abgestimmt. Die Icon-Bibliothek bietet über 300 Icons in drei Stilen: outline (2px Stroke, kein Fill), solid (Fill, kein Stroke) und mini (16px, kompakter für eng beieinander liegende UI-Elemente). Für Tailwind-Projekte ist die Outline-Variante der Standard für Navigation, Buttons und Formulare. Die Solid-Variante ist für dekorative Elemente und aktive Zustände geeignet.
In Hyvä-Magento-Projekten nutzt man Heroicons direkt als Inline-SVG in .phtml-Templates. Das Icon-SVG wird von heroicons.com kopiert, in das Template eingefügt und mit Tailwind-Klassen (class="w-5 h-5") versehen. Alternativ kann man für die komponentenbasierte Verwendung PHP-Helper-Methoden bauen, die Icons nach Namen auflösen und als SVG-String zurückgeben. In Tailwind-CSS-Projekten mit Build-Step (z.B. Vite + Vue) ist das NPM-Paket @heroicons/vue oder @heroicons/react die schnellste Integration – im Hyvä-Kontext ist Inline-SVG die Standardlösung.
<!-- Heroicons inline SVG examples with Tailwind sizing and color -->
<!-- Outline style: 24px, stroke-based, inherits text color -->
<button class="flex items-center gap-2 text-slate-700 hover:text-sky-600 transition-colors font-medium text-sm">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 15.803 7.5 7.5 0 0016.803 15.803z"/>
</svg>
Suchen
</button>
<!-- Solid style: fill-based, great for filled states -->
<span class="flex items-center gap-1.5 text-emerald-600 text-sm font-semibold">
<svg class="w-4 h-4" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd"/>
</svg>
Verifiziert
</span>
<!-- Mini style (16px): compact, for badges and tight UIs -->
<span class="inline-flex items-center gap-1 bg-sky-100 text-sky-700 px-2.5 py-0.5 rounded-full text-xs font-semibold">
<svg class="w-3.5 h-3.5" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
<path d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8z"/>
<path d="M6.5 7.75A.75.75 0 017.25 7h1a.75.75 0 01.75.75v2.75h.25a.75.75 0 010 1.5h-2a.75.75 0 010-1.5h.25v-2h-.25a.75.75 0 01-.75-.75z"/>
<path d="M8 6a1 1 0 100-2 1 1 0 000 2z"/>
</svg>
Info
</span>
<!-- Icon-only button: aria-label required for screen readers -->
<button
aria-label="Benachrichtigungen öffnen"
class="relative p-2 text-slate-500 hover:text-slate-800 hover:bg-slate-100 rounded-lg transition-colors">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0"/>
</svg>
<!-- Notification badge -->
<span class="absolute top-1 right-1 w-2 h-2 bg-red-500 rounded-full" aria-hidden="true"></span>
</button>
3. Phosphor Icons: Flexibilität durch mehrere Stile
Phosphor Icons ist eine jüngere, sehr umfangreiche Icon-Bibliothek mit über 1.200 Icons in sechs Stilen: Regular, Bold, Thin, Light, Fill und Duotone. Der Duotone-Stil ist das Alleinstellungsmerkmal von Phosphor: Er kombiniert zwei Farbtöne innerhalb eines Icons und ergibt einen markanten Effekt, der sich mit Tailwinds text-{color} und fill-Attributen steuern lässt. Für Projekte, die eine reichere Icon-Sprache benötigen oder vom saubereren Heroicons-Stil abweichen wollen, ist Phosphor die empfehlenswerteste Alternative.
Phosphor Icons lässt sich in Tailwind-Projekten als NPM-Paket (@phosphor-icons/web) mit Web-Component-Syntax (<ph-icon icon="arrow-right" />) einbinden oder als Inline-SVG aus phosphoricons.com. Für Hyvä-Magento-Projekte, die kein JavaScript-Bundle verwenden, ist Inline-SVG die korrekte Wahl. Die SVG-Paths von Phosphor folgen einer konsistenten Viewbox von 256x256 – man passt Größe und Farbe über Tailwind-Klassen an, analog zu Heroicons. Der Bold-Stil ist für kleine Icons auf hellen Hintergründen besonders gut lesbar.
4. Größe und Farbe mit Tailwind steuern
Das eleganteste Feature von Tailwind Icons ist die nahtlose Integration in das Utility-System für Größe und Farbe. Größe steuert man mit w-{n} h-{n}: w-4 h-4 für 16px, w-5 h-5 für 20px, w-6 h-6 für 24px. Das sind die drei gängigsten Icon-Größen in UI-Systemen. Für Display-Icons in leeren Zuständen oder Illustrationen nutzt man w-12 h-12 oder w-16 h-16. Durch die quadratische Form mit gleicher Breite und Höhe bleibt das Seitenverhältnis immer korrekt.
Farbe steuert man über text-{color} auf dem SVG-Element oder auf einem übergeordneten Element – Voraussetzung ist, dass das SVG fill="currentColor" (für Fill-basierte Icons) oder stroke="currentColor" (für Stroke-basierte Icons wie Heroicons Outline) verwendet. Dann erbt das SVG den CSS-color-Wert. Das erlaubt Farb-Kaskaden: Ein Button mit text-slate-700 hover:text-sky-600 ändert beim Hover automatisch die Icon-Farbe mit, ohne dass hover:-Klassen direkt auf das SVG gesetzt werden müssen. Für Duotone-Icons (Phosphor) kann man die zweite Farbe über opacity-Attribute auf bestimmten Paths steuern.
<!-- Icon size and color control with Tailwind utilities -->
<!-- Size scale: 4 → 5 → 6 → 8 → 12 -->
<div class="flex items-end gap-4 text-sky-600">
<!-- 16px: for badges, compact UI elements -->
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
</svg>
<!-- 20px: standard button icon -->
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
</svg>
<!-- 24px: navigation, feature icons -->
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
</svg>
<!-- 48px: empty states, feature illustrations -->
<svg class="w-12 h-12" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
</svg>
</div>
<!-- Color cascade: parent color propagates to child SVG -->
<button class="flex items-center gap-2 text-slate-600 hover:text-sky-600 transition-colors text-sm font-medium">
<!-- Icon automatically changes color on parent hover via currentColor -->
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
<path fill-rule="evenodd" d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" clip-rule="evenodd"/>
</svg>
Zu Favoriten hinzufügen
</button>
5. Barrierefreiheit: aria-hidden, aria-label und title
Barrierefreiheit bei Tailwind Icons folgt zwei klaren Regeln. Erstens: Dekorative Icons, die neben sichtbarem Text stehen, bekommen aria-hidden="true". Screen-Reader ignorieren das Icon und lesen nur den Text vor – der Text ist die vollständige Beschreibung. Das verhindert doppelte Ausgabe: "Suchen-Icon Suchen" statt "Suchen". Zweitens: Icons, die allein stehen und eine Funktion ausführen (Icon-only-Buttons), brauchen eine textliche Beschriftung für Screen-Reader. Das kann entweder aria-label auf dem Button oder ein title-Element als erstes Kind des SVG sein.
Die Entscheidungsregel: Hat das interaktive Element einen sichtbaren Textlabel? Dann aria-hidden="true" auf dem SVG. Kein sichtbares Label? Dann aria-label="Beschreibung" auf dem Button/Link, und aria-hidden="true" auf dem SVG. Das <title>-Element direkt im SVG ist die W3C-konforme Methode, wird aber von Screen-Readern unterschiedlich interpretiert – aria-label auf dem interaktiven Element ist konsistenter. Für rein dekorative, nicht interaktive Icons (Schmuck-Icons in Feature-Sections) ist aria-hidden="true" immer ausreichend und korrekt.
6. Inline-SVG: wann und wie
Inline-SVG ist die Standardmethode für Tailwind Icons in Projekten ohne JavaScript-Build-Pipeline – also in klassischen PHP/Magento-Projekten mit Hyvä Themes. Der Vorteil: kein HTTP-Request, kein Render-Blocking, volle Farbsteuerung über currentColor. Der Nachteil: Das HTML wird größer, und dasselbe Icon-SVG muss bei Mehrfachverwendung mehrfach im HTML stehen. Für Icons, die auf einer Seite nur ein oder zweimal vorkommen, ist das kein Problem. Für Icons, die hundert Mal auf einer Produktlisting-Seite wiederholt werden (Stern-Bewertungen, Warenkorb-Icons), ist die SVG-Sprite-Technik die bessere Wahl.
Beim Einbinden von Inline-SVG sollte man immer die irrelevanten Attribute entfernen: xmlns ist im HTML5-Kontext optional, width- und height-Attribute werden durch Tailwind-Klassen überschrieben und können wegfallen, id-Attribute sollten nicht aus der Bibliothek übernommen werden, wenn mehrere Icons einer Seite gleiche IDs bekämen. Ein bereinigtes SVG aus Heroicons sieht in Tailwind so aus: <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"> mit nur dem relevanten path-Element innen.
7. SVG-Sprites für skalierbare Icon-Systeme
SVG-Sprites lösen das Wiederholungs-Problem von Inline-SVG: Alle Icons werden in einer einzigen SVG-Sprite-Datei gesammelt, die einmal geladen und gecacht wird. Jedes Icon ist ein <symbol>-Element mit einer eindeutigen id. An der Verwendungsstelle referenziert man das Icon mit <use href="/icons/sprite.svg#icon-name">. Das HTML bleibt kompakt, und das Icon kann beliebig oft ohne Code-Duplizierung verwendet werden.
In Tailwind-Projekten gestaltet man den Icon-Aufruf als minimales Inline-SVG-Wrapper-Element: <svg class="w-5 h-5 text-sky-600" aria-hidden="true"><use href="/icons/sprite.svg#search"></use></svg>. Größe und Farbe werden weiterhin über Tailwind-Klassen auf dem äußeren SVG-Element gesteuert. Der <use>-Ansatz hat einen Nachteil: Externe SVG-Sprite-Dateien können nicht über CSS currentColor manipuliert werden, wenn die Sprite-Datei über einen separaten HTTP-Request geladen wird (CORS-Einschränkungen). Das lässt sich mit einem Inline-Sprite am Seitenanfang (das gesamte Sprite einmalig als verstecktes SVG in den Body) lösen – dann funktioniert currentColor wieder.
<!-- SVG Sprite: hidden sprite definition at top of page body -->
<svg class="sr-only" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- search icon symbol -->
<symbol id="icon-search" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 15.803 7.5 7.5 0 0016.803 15.803z"/>
</symbol>
<!-- heart icon symbol -->
<symbol id="icon-heart" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z"/>
</symbol>
<!-- star icon symbol -->
<symbol id="icon-star" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z"/>
</symbol>
</defs>
</svg>
<!-- Usage: use href="#id" — inherits currentColor from parent svg element -->
<button aria-label="Suchen" class="p-2 text-slate-500 hover:text-sky-600 transition-colors">
<svg class="w-5 h-5" fill="none" stroke="currentColor" aria-hidden="true">
<use href="#icon-search"/>
</svg>
</button>
<!-- Star rating with repeated icon — no duplication of SVG path -->
<div class="flex gap-0.5 text-amber-400" aria-label="Bewertung: 4 von 5 Sternen">
<svg class="w-4 h-4" fill="currentColor" aria-hidden="true"><use href="#icon-star"/></svg>
<svg class="w-4 h-4" fill="currentColor" aria-hidden="true"><use href="#icon-star"/></svg>
<svg class="w-4 h-4" fill="currentColor" aria-hidden="true"><use href="#icon-star"/></svg>
<svg class="w-4 h-4" fill="currentColor" aria-hidden="true"><use href="#icon-star"/></svg>
<svg class="w-4 h-4" fill="none" stroke="currentColor" aria-hidden="true"><use href="#icon-star"/></svg>
</div>
8. Hover- und Übergangsanimationen auf Icons
Animierte Icons machen Interfaces lebendiger und geben Nutzern präzises Feedback bei Interaktionen. Mit Tailwind CSS lassen sich einfache Icon-Animationen vollständig ohne JavaScript realisieren. Das grundlegende Muster: transition-transform duration-200 auf dem SVG-Element, und Hover-Transformation über hover:translate-x-1 (Pfeil-Icons, die nach rechts zeigen, schieben sich nach rechts), hover:scale-110 (Icons, die beim Hover leicht anwachsen) oder hover:rotate-12 (Einstellungs-Icons, die sich drehen).
Komplexere Animationen – etwa ein Stern, der beim Klick ausfüllt – benötigen den State-Wechsel, den man mit dem peer-checked-Muster (für Formular-Checkboxen) oder Alpine.js (x-data, :class) umsetzen kann. Das Wishlist-Herz-Icon ist ein klassisches Beispiel: Outline-Herz initial, Solid-Herz wenn hinzugefügt. Mit Alpine.js und dem Tailwind hidden/block-Toggle ist das in wenigen Zeilen implementiert. Das SVG selbst braucht keine spezielle Klasse – Tailwind Icons sind vollständig kompatibel mit Alpine.js-State-Management.
<!-- Animated icons with Tailwind transitions and Alpine.js state -->
<!-- Arrow icon: slides right on hover (parent hover, via group) -->
<a href="/mehr" class="group inline-flex items-center gap-2 text-sky-600 font-semibold text-sm hover:text-sky-700">
Mehr erfahren
<svg class="w-4 h-4 transition-transform duration-200 group-hover:translate-x-1"
fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
</svg>
</a>
<!-- Settings icon: rotates 90deg on hover -->
<button class="p-2 text-slate-400 hover:text-slate-700 transition-colors rounded-lg hover:bg-slate-100">
<svg class="w-5 h-5 transition-transform duration-300 hover:rotate-90"
fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-label="Einstellungen">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 010 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 010-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
</button>
<!-- Wishlist heart: toggle with Alpine.js state -->
<div x-data="{ liked: false }">
<button
@click="liked = !liked"
:aria-label="liked ? 'Von Wunschliste entfernen' : 'Zur Wunschliste hinzufügen'"
:class="liked ? 'text-red-500 hover:text-red-600' : 'text-slate-400 hover:text-red-500'"
class="p-2 transition-colors duration-200 rounded-lg">
<!-- Outline heart: visible when not liked -->
<svg x-show="!liked" class="w-5 h-5 transition-transform duration-200 hover:scale-110"
fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z"/>
</svg>
<!-- Solid heart: visible when liked -->
<svg x-show="liked" x-cloak class="w-5 h-5"
fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path d="M11.645 20.91l-.007-.003-.022-.012a15.247 15.247 0 01-.383-.218 25.18 25.18 0 01-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0112 5.052 5.5 5.5 0 0116.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 01-4.244 3.17 15.247 15.247 0 01-.383.219l-.022.012-.007.004-.003.001a.752.752 0 01-.704 0l-.003-.001z"/>
</svg>
</button>
</div>
9. Icon-Ansätze im Vergleich
Die Wahl des richtigen Icon-Ansatzes in einem Tailwind-Projekt hängt von der Projektgröße, der Build-Pipeline und der Anzahl einzigartiger vs. wiederholter Icons ab.
| Ansatz | Farbsteuerung via Tailwind | HTTP-Requests | Beste Eignung |
|---|---|---|---|
| Inline-SVG (Heroicons) | Vollständig via currentColor | 0 (im HTML) | Standard für die meisten Tailwind-Projekte |
| Inline-Sprite (body) | Vollständig via currentColor | 0 (im HTML) | Viele Wiederholungen desselben Icons |
| Externer SVG-Sprite | Eingeschränkt (CORS) | 1 gecachter Request | Große Icon-Bibliotheken, wenn Farbe fix |
| Icon-Font (Font Awesome) | Eingeschränkt (font-Rendering) | 1+ (Font-Files) | Legacy-Projekte, Migration nötig |
| PNG/JPEG Icon | Keine | 1 pro Icon | Nur für komplexe Illustrationen, nicht für UI-Icons |
Für neue Tailwind-Projekte mit Hyvä Themes ist Inline-SVG mit Heroicons die klare Empfehlung: kein Build-Step nötig, vollständige Farbkontrolle, null extra HTTP-Requests. Für Produktlisting-Seiten mit Stern-Bewertungen (die auf jeder Produktkarte erscheinen) ist der Inline-Sprite die effizientere Lösung. Icon-Fonts sollten in neuen Projekten nicht eingesetzt werden – die Performance- und Barrierefreiheits-Nachteile überwiegen jeden Komfortvorteil.
Mironsoft
Tailwind CSS · SVG Icons · Hyvä Themes · Barrierefreiheit
Icon-System für Ihr Tailwind-Projekt?
Wir bauen konsistente, barrierefreie Icon-Systeme mit Heroicons und SVG-Sprites – integriert in Tailwind CSS v4 und Hyvä Themes, mit vollständiger Keyboard- und Screen-Reader-Unterstützung.
Icon-Audit
Bestehende Icon-Fonts analysieren, Barrierefreiheit prüfen und Migrationsplan erstellen
Sprite-Aufbau
SVG-Sprite-System mit Heroicons oder Phosphor für Ihr Projekt einrichten
Hyvä-Integration
PHP-Helper-Methoden für Icon-Ausgabe in Magento phtml-Templates
10. Zusammenfassung
SVG-Icons mit Tailwind CSS sind der einzig sinnvolle Ansatz für moderne Webprojekte: keine Font-Dateien, keine Render-Blocking-Ressourcen, vollständige Farbkontrolle über currentColor und text-{color}-Klassen. Heroicons ist die natürliche Ergänzung für Tailwind-Projekte: konsistenter Stil, drei Varianten (Outline, Solid, Mini) und dieselben Design-Werte wie Tailwind selbst. Phosphor Icons erweitert die Möglichkeiten für Projekte, die Duotone-Icons oder andere Stile benötigen.
Die Barrierefreiheitsregeln sind simpel: aria-hidden="true" für dekorative Icons neben Text, aria-label auf dem interaktiven Element für Icon-only-Buttons. Für Seiten mit vielen Wiederholungen desselben Icons ist der Inline-Sprite die performanteste Lösung ohne HTTP-Request-Overhead und ohne CORS-Einschränkungen bei der Farbsteuerung. Animationen – Hover-Transformationen, State-Wechsel mit Alpine.js – sind vollständig mit Tailwind-Transitions und Alpine.js-x-show/:class umsetzbar.
Tailwind Icons — Das Wichtigste auf einen Blick
Farbsteuerung
SVG mit fill="currentColor" oder stroke="currentColor". Dann steuert text-{color} auf dem SVG oder Elternelement die Icon-Farbe – inklusive hover:-Kaskaden.
Barrierefreiheit
Dekorativ neben Text: aria-hidden="true". Icon-only-Button: aria-label="..." auf dem Button, aria-hidden="true" auf dem SVG.
Sprite vs. Inline
Inline-SVG für einmalige Icons. Inline-Sprite im Body für Icons, die mehrfach auf einer Seite vorkommen (Sterne, Warenkorb-Icons in Listings).
Größen-Standards
w-4 h-4 (16px, Badges), w-5 h-5 (20px, Buttons), w-6 h-6 (24px, Navigation), w-12 h-12 (48px, Empty States). Immer w und h gleich setzen.