Rating- und Sternebewertung-Komponenten mit Tailwind CSS bauen
AI generated
tw
Tailwind CSS · UI-Pattern · Rating
Rating- und Sternebewertung-Komponenten
Halbe Sterne, Hover-Vorschau und Barrierefreiheit mit Tailwind sauber umsetzen

Sternebewertungen wirken auf den ersten Blick wie eine triviale Komponente, doch sobald halbe Sterne, eine interaktive Eingabe mit Hover-Vorschau und eine barrierefreie Umsetzung gleichzeitig gefordert sind, stecken mehr Detailprobleme darin als man denkt. Dieser Artikel zeigt, wie sich sowohl die read-only Anzeige einer Durchschnittsbewertung als auch die editierbare Eingabe-Variante mit Tailwind CSS sauber umsetzen lassen, inklusive der präzisen Darstellung halber Sterne und einer Barrierefreiheit, die nicht allein auf visuellen Sternen beruht.

14 Min. Lesezeit Star Rating Bewertungssystem

1. Warum Sternebewertungen mehr Sorgfalt brauchen als man denkt

Eine Sternebewertung transportiert auf sehr kleinem visuellem Raum eine präzise numerische Information, meist eine Zahl zwischen null und fünf, oft mit einer Nachkommastelle. Genau diese Präzision macht die Umsetzung anspruchsvoller als bei den meisten anderen UI-Komponenten: Ein Durchschnittswert von 3.7 muss visuell auch tatsächlich als 3.7 und nicht als grob gerundete 4 erkennbar sein, sonst verliert die Bewertung an Aussagekraft. Gleichzeitig muss dieselbe visuelle Sprache sowohl für eine rein lesende Anzeige als auch für eine interaktive Eingabe funktionieren, bei der Nutzer per Hover und Klick selbst eine Bewertung abgeben.

Hinzu kommt, dass Sterne als rein visuelles Symbol grundsätzlich ein Barrierefreiheits-Problem darstellen, wenn die zugrundeliegende Zahl nicht auch textuell zugänglich gemacht wird. Wer nur fünf gefüllte oder leere Symbole ins DOM schreibt, macht die Bewertung für Screenreader-Nutzer faktisch unsichtbar. Dieser Artikel behandelt daher sowohl die rein visuelle Umsetzung mit Tailwind als auch die semantische Ebene, die bei den meisten Rating-Implementierungen im Web nachlässig behandelt wird.

2. Sterne mit Gradient-Fill als Füllstands-Basis

Der robusteste Ansatz für präzise Füllstände, auch bei krummen Werten wie 3.7, ist eine Gradient-Füllung statt einer reinen Klassen-Umschaltung zwischen gefüllt und leer. Jeder Stern besteht dabei aus zwei übereinandergelegten Symbolen: einem grauen Hintergrund-Stern als Basis und einem farbigen Vordergrund-Stern, dessen sichtbarer Anteil über einen linearen Gradient auf exakt den Prozentsatz begrenzt wird, der dem Füllstand entspricht. Bei einem Gesamtwert von 3.7 bekommen die ersten drei Sterne einen vollen Farbanteil, der vierte Stern einen Gradient-Stopp bei 70 Prozent und der fünfte bleibt komplett grau.

Technisch lässt sich das mit Tailwind über eine Kombination aus relative-Container, einem absolut positionierten Overlay-Stern und einer Inline-Style-Deklaration für den exakten Prozentwert umsetzen, da Tailwind selbst keine dynamischen Prozentwerte als Utility-Klasse anbietet. Die Basisklassen für Größe, Farbe und Positionierung kommen vollständig aus Tailwind, nur der variable Füllstand selbst wird als CSS-Custom-Property oder Inline-Style gesetzt, was diesen einen dynamischen Wert sauber von der ansonsten statischen Utility-Struktur trennt.


<div class="flex items-center gap-0.5" role="img" aria-label="3,7 von 5 Sternen">
  <template x-for="i in 5" :key="i">
    <span class="relative inline-block h-5 w-5" aria-hidden="true">
      <!-- Hintergrund: immer grau, volle Sternform -->
      <svg class="absolute inset-0 h-5 w-5 text-slate-200" viewBox="0 0 20 20" fill="currentColor">
        <path d="M10 1.5l2.7 5.8 6.3.6-4.7 4.3 1.3 6.2L10 15.3l-5.6 3.1 1.3-6.2L1 7.9l6.3-.6z" />
      </svg>
      <!-- Vordergrund: gelb, per Clip-Path auf Füllstand begrenzt -->
      <svg
        class="absolute inset-0 h-5 w-5 text-amber-400"
        viewBox="0 0 20 20"
        fill="currentColor"
        :style="`clip-path: inset(0 ${100 - Math.max(0, Math.min(100, (rating - (i - 1)) * 100))}% 0 0)`">
        <path d="M10 1.5l2.7 5.8 6.3.6-4.7 4.3 1.3 6.2L10 15.3l-5.6 3.1 1.3-6.2L1 7.9l6.3-.6z" />
      </svg>
    </span>
  </template>
</div>

3. Halbe Sterne: Clip-Path versus Gradient im Vergleich

Für den häufigen Sonderfall, in dem nur halbe Sterne vorkommen, also Bewertungen in 0.5er-Schritten statt beliebiger Kommazahlen, reicht oft ein einfacherer Ansatz mit genau drei Zuständen pro Stern: leer, halb und voll. Der halbe Zustand lässt sich entweder über clip-path: inset(0 50% 0 0) auf dem farbigen Vordergrund-Stern lösen, wie im vorherigen Codebeispiel mit fest 50 Prozent statt einem dynamischen Wert, oder über einen linearen Gradient direkt in der SVG-Definition mit zwei Farbstopps bei exakt 50 Prozent.

Der Clip-Path-Ansatz ist einfacher zu verstehen und zu debuggen, da er direkt mit sichtbaren Prozentwerten arbeitet, während die Gradient-Variante etwas mehr SVG-Vorwissen voraussetzt, dafür aber auch weichere Übergänge bei nicht-runden Prozentwerten ermöglicht, etwa bei den bereits erwähnten präzisen Durchschnittsbewertungen. Für die meisten Anwendungsfälle, in denen Nutzer nur ganze oder halbe Sterne vergeben können, reicht der Clip-Path-Ansatz vollkommen aus und bleibt deutlich wartungsfreundlicher, da keine SVG-Gradient-Definitionen separat gepflegt werden müssen.

4. Interaktive Hover-Vorschau bei der Bewertungs-Eingabe

Bei der editierbaren Variante muss jeder Stern einzeln auf Hover reagieren und dabei eine Vorschau anzeigen, wie die Bewertung aussehen würde, wenn der Nutzer jetzt an dieser Position klickt. Das bedeutet, dass alle Sterne bis zur Hover-Position farbig gefüllt dargestellt werden, während die tatsächlich bereits gespeicherte Bewertung erst nach Verlassen des gesamten Rating-Bereichs wieder sichtbar wird. Mit Alpine.js lässt sich das über eine separate hoverIndex-Variable lösen, die getrennt von der eigentlichen rating-Variable geführt wird und beim mouseleave auf dem Container auf null zurückgesetzt wird.

Wichtig ist, dass die Hover-Vorschau visuell klar als vorläufig erkennbar bleibt und sich nicht komplett wie die finale Auswahl anfühlt, meist durch eine minimal reduzierte Deckkraft oder einen leichten Skalierungs-Effekt auf dem gehoverten Stern selbst. Der eigentliche Klick setzt dann den finalen Wert, und ein kurzer visueller Bestätigungs-Effekt, etwa ein kurzes Aufblitzen oder eine kleine Skalierungs-Animation, gibt dem Nutzer Feedback, dass die Bewertung tatsächlich übernommen wurde und nicht nur vorübergehend als Hover-Zustand sichtbar ist.

5. Read-only-Anzeige versus editierbare Eingabe

Die read-only Variante, wie sie typischerweise unter einem Produktnamen als Durchschnittsbewertung erscheint, braucht keinerlei Hover- oder Klick-Handler und sollte auch keinen Cursor-Pointer anzeigen, der fälschlich Interaktivität suggeriert. Hier reicht die reine Gradient- oder Clip-Path-Darstellung aus dem vorherigen Abschnitt vollständig aus, ergänzt um einen begleitenden Text mit dem exakten Zahlenwert und der Anzahl der Bewertungen, etwa '4,3 von 5 (128 Bewertungen)', da die reine visuelle Darstellung allein selten präzise genug abgelesen werden kann.

Die editierbare Variante dagegen braucht zwingend einen cursor-pointer auf jedem einzelnen Stern, eine sichtbare Hover-Vorschau wie im vorherigen Abschnitt beschrieben, und in der Regel auch eine Möglichkeit, die Bewertung wieder zu löschen, etwa durch erneutes Klicken auf den bereits aktiven letzten Stern. Beide Varianten sollten sich im Code klar durch eine Prop oder ein Flag wie readonly unterscheiden lassen, damit dieselbe Basis-Komponente für beide Fälle wiederverwendet werden kann, statt zwei komplett getrennte Implementierungen zu pflegen.

6. Barrierefreiheit: aria-label statt reiner visueller Darstellung

Da Sterne rein dekorative SVG-Grafiken sind, tragen sie für sich genommen keine für Screenreader zugängliche Information, selbst wenn ihr Füllstand visuell absolut korrekt dargestellt wird. Die gesamte Sterne-Gruppe braucht daher einen umschließenden Container mit role="img" und einem aria-label, das den exakten Wert in Textform enthält, etwa 'aria-label="3,7 von 5 Sternen"', während jeder einzelne Stern innerhalb der Gruppe aria-hidden="true" bekommt, damit Screenreader nicht fälschlich fünf einzelne, bedeutungslose Grafiken vorlesen.

Bei der editierbaren Variante reicht ein reiner role="img" nicht mehr aus, da die Komponente jetzt interaktiv ist. Hier bietet sich eine semantische Radio-Gruppe an, bei der jeder Stern als role="radio" innerhalb einer role="radiogroup" fungiert, mit einem eigenen aria-label pro Stern wie 'aria-label="4 Sterne vergeben"'. Diese Struktur erlaubt zusätzlich eine native Tastatur-Navigation mit den Pfeiltasten zwischen den einzelnen Bewertungsstufen, was bei einer reinen Klick-Interaktion ohne semantische Struktur komplett fehlen würde.

7. Größenvarianten für unterschiedliche Kontexte

Sternebewertungen tauchen in sehr unterschiedlichen Kontexten auf, von einer kompakten Anzeige in einer Produktliste bis zu einer prominenten Eingabe-Komponente auf einer Bewertungs-Detailseite, und brauchen entsprechend unterschiedliche Größen. Mit Tailwind lässt sich das sauber über ein kleines Set fester Größenklassen lösen, etwa h-3.5 w-3.5 für die kompakte Listenansicht, h-5 w-5 als Standardgröße und h-8 w-8 für die große, interaktive Eingabe-Variante, statt beliebige Zwischenwerte zuzulassen, die die visuelle Konsistenz der gesamten Anwendung untergraben würden.

Bei der kompakten Größe lohnt es sich zusätzlich, den Abstand zwischen den einzelnen Sternen zu reduzieren, etwa von gap-0.5 auf einen noch engeren Wert, da fünf Sterne mit vollem Standardabstand in einer engen Produktliste schnell zu viel horizontalen Platz beanspruchen. Bei der großen, interaktiven Variante dagegen darf der Abstand ruhig großzügiger ausfallen, da hier jeder einzelne Stern ein eigenständiges, gut treffbares Klick-Ziel darstellen muss, besonders auf Touch-Geräten.

8. Farbthemen und Dark-Mode-Anpassung

Die klassische Sternfarbe ist ein warmes Gelb oder Amber, meist text-amber-400, das sich auf hellem Hintergrund gut vom neutralen Grau des unausgefüllten Sterns abhebt. Im Dark Mode muss diese Farbe angepasst werden, da ein zu gedämpftes Amber auf dunklem Hintergrund an Kontrast verliert, während der graue Hintergrund-Stern im Dark Mode ebenfalls von einem hellen Grau auf einen dunkleren Grauton wie dark:text-slate-600 wechseln sollte, um nicht selbst wie ein aktiver Stern zu wirken.

Für Anwendungen mit einem eigenen Marken-Farbschema kann die Sternfarbe grundsätzlich durch die primäre Akzentfarbe ersetzt werden, wichtig ist dabei nur, dass der Kontrast zwischen gefülltem und leerem Zustand in beiden Farbmodi deutlich genug bleibt, idealerweise mit einem Kontrastverhältnis von mindestens 3:1 zwischen den beiden Zuständen. Ein zu subtiler Unterschied zwischen Voll- und Leerzustand macht die Bewertung schwer ablesbar, besonders bei kleiner Darstellungsgröße in Produktlisten.

9. SVG-Icons versus Icon-Fonts für Sterne

Für die Sternform selbst bieten sich zwei technische Ansätze an: Inline-SVG-Pfade wie im Codebeispiel oben, oder eine Icon-Font mit Sternzeichen, deren Füllung über die CSS-Farbe des Font-Zeichens gesteuert wird. Inline-SVG hat den klaren Vorteil, dass sich der Füllstand präzise per Clip-Path oder Gradient steuern lässt, während eine Icon-Font für halbe oder krumme Füllstände auf einen zweiten, überlagerten Font-Charakter mit Clip-Path angewiesen ist, was in der Praxis kaum einfacher ist als die SVG-Variante.

Zusätzlich vermeidet Inline-SVG das bekannte Problem des kurzen Aufblitzens ungestylter Zeichen, das bei extern geladenen Icon-Fonts auftreten kann, bevor die Font-Datei vollständig geladen ist. Da Sterne meist above-the-fold und damit sofort sichtbar sind, sollte dieses Aufblitzen unbedingt vermieden werden, weshalb Inline-SVG für Rating-Komponenten in aller Regel die robustere und empfehlenswertere Wahl gegenüber Icon-Fonts darstellt.

Variante Größe (Tailwind) Interaktion Aria-Rolle
Kompakt (Liste) h-3.5 w-3.5 Keine, rein lesend role="img"
Standard (read-only) h-5 w-5 Keine, rein lesend role="img"
Editierbar (Formular) h-8 w-8 Hover-Vorschau + Klick role="radiogroup"
Kompakt editierbar h-5 w-5 Klick ohne Hover-Vorschau role="radiogroup"

Mironsoft

Tailwind-CSS-Architektur, Design-Systeme und Performance

Tailwind-Frontends, die trotz tausender Utility-Klassen wartbar bleiben?

Wir prüfen bestehende Tailwind-Projekte auf aufgeblähte Klassenlisten, inkonsistente Design-Tokens und ungenutzte CSS-Reste und bauen daraus ein Design-System, das sich sauber skaliert statt mit jeder Komponente unübersichtlicher zu werden.

Design-System-Review

Tokens, Spacing-Skala und Komponentenkonsistenz auf Wartbarkeit prüfen.

Performance-Optimierung

CSS-Bundle-Größe, Purge-Konfiguration und Ladezeiten systematisch reduzieren.

Component-Architektur

Wiederverwendbare, gut strukturierte Komponenten statt Klassenlisten-Wildwuchs aufbauen.

10. Zusammenfassung

Rating- und Sternebewertung-Komponenten mit Tailwind: Das Wichtigste auf einen Blick

Füllstand

Gradient oder Clip-Path für präzise Prozentwerte, nicht nur grobe gefüllt/leer-Umschaltung.

Hover-Vorschau

Separate Hover-Variable getrennt vom gespeicherten Wert, mit klarer visueller Unterscheidung.

Barrierefreiheit

role=img mit aria-label für read-only, role=radiogroup mit Tastaturnavigation für editierbar.

Technik

Inline-SVG statt Icon-Font, wegen präziser Clip-Path-Steuerung und ohne Füllungs-Aufblitzen.

11. FAQ: Rating- und Sternebewertung-Komponenten mit Tailwind: Das Wichtigste auf einen Blick

1Warum reicht eine einfache gefüllt/leer-Klasse pro Stern nicht immer aus?
Bei krummen Durchschnittswerten wie 3,7 kann ein einzelner Stern nicht mehr binär gefüllt oder leer sein. Ein Gradient oder Clip-Path erlaubt es, den exakten Prozentsatz eines einzelnen Sterns visuell abzubilden.
2Ist Clip-Path oder ein SVG-Gradient die bessere Wahl für halbe Sterne?
Für feste halbe Schritte ist Clip-Path einfacher zu verstehen und zu debuggen. Ein SVG-Gradient lohnt sich vor allem, wenn beliebige, nicht-runde Prozentwerte dargestellt werden müssen.
3Wie verhindert man, dass die Hover-Vorschau mit der gespeicherten Bewertung verwechselt wird?
Beide Werte sollten in getrennten Variablen geführt werden, wobei die Hover-Variable beim Verlassen des Containers sofort zurückgesetzt wird. Ein leichter visueller Unterschied, etwa reduzierte Deckkraft, hilft zusätzlich.
4Warum braucht die read-only Variante trotzdem ein aria-label?
Weil die Sterne selbst als SVG-Grafiken keine für Screenreader interpretierbare Information tragen. Ohne aria-label bleibt die Bewertung für Screenreader-Nutzer komplett unsichtbar, unabhängig von der visuellen Präzision.
5Sollte die Anzahl der Bewertungen immer mit angezeigt werden?
Ja, wo verfügbar. Eine reine Sternzahl ohne Kontext zur Stichprobengröße kann irreführend sein, da fünf Sterne aus einer einzigen Bewertung eine andere Aussagekraft haben als aus 500.
6Wie groß sollten die Klick-Ziele bei der editierbaren Variante mindestens sein?
Für Touch-Geräte sollte das gesamte klickbare Element pro Stern mindestens 44 mal 44 Pixel groß sein, auch wenn die sichtbare Sternform selbst kleiner ist. Padding um das SVG herum löst das einfach.
7Kann man Sternebewertungen komplett ohne JavaScript nur mit CSS umsetzen?
Für die read-only Anzeige ja, über reines CSS mit Gradient oder Clip-Path. Für die interaktive Hover-Vorschau und den Klick-Handler wird aber JavaScript oder ein Framework wie Alpine.js benötigt.
8Wie geht man mit Tastatur-Navigation bei der editierbaren Variante um?
Mit role=radiogroup und role=radio pro Stern funktioniert die Pfeiltasten-Navigation nativ über die Browser-Semantik. Die Leertaste oder Enter übernimmt dann die aktuell fokussierte Bewertung als Klick-Aequivalent.
9Warum wird Inline-SVG gegenüber Icon-Fonts für Sterne empfohlen?
Inline-SVG erlaubt präzise Clip-Path- und Gradient-Steuerung ohne zusätzliche Font-Datei, und vermeidet das kurze Aufblitzen ungestylter Zeichen beim Laden externer Icon-Fonts, das bei above-the-fold-Inhalten besonders stört.
10Sollte die Sternfarbe an das Marken-Farbschema angepasst werden?
Das ist möglich und üblich, solange der Kontrast zwischen gefülltem und leerem Zustand deutlich genug bleibt. Ein Kontrastverhältnis von mindestens 3:1 zwischen beiden Zuständen sollte dabei nicht unterschritten werden.