Vertikale Linie, Icon-Badges und responsives Verhalten mit Tailwind umsetzen
Ob Bestellverlauf, Audit-Log oder Aktivitäts-Feed eines Projekts: Chronologisch geordnete Ereignisse gehören zu den häufigsten wiederkehrenden UI-Mustern in Webanwendungen. Optisch stecken darin mehr Details als es zunächst scheint, von der vertikalen Verbindungslinie zwischen den Ereignissen über Icon-Badges pro Ereignistyp bis zum Umgang mit unterschiedlich langen Beschreibungstexten, die das Raster nicht durcheinanderbringen dürfen. Dieser Artikel zeigt, wie sich eine Timeline-Komponente mit reinem Tailwind CSS strukturiert aufbauen lässt und wo sich eine kompakte Activity-Liste von einer ausführlichen Timeline-Ansicht unterscheidet.
Inhaltsverzeichnis
- 1. Timeline und Activity Feed: zwei verwandte, aber unterschiedliche Muster
- 2. Die vertikale Linie mit Punkten aufbauen
- 3. Icon-Badges pro Ereignistyp
- 4. Responsives Verhalten bei langen Beschreibungstexten
- 5. Kompakte Aktivitäts-Liste versus ausführliche Timeline
- 6. Zeitstempel: relative Zeit versus absolutes Datum
- 7. Gruppierung nach Tagen mit eigenen Datums-Headern
- 8. Statusbasierte Farbcodierung über die gesamte Timeline
- 9. Barrierefreiheit: Semantik statt reiner Optik
- 10. Zusammenfassung
- 11. FAQ
1. Timeline und Activity Feed: zwei verwandte, aber unterschiedliche Muster
Beide Komponenten stellen eine Abfolge von Ereignissen entlang einer Zeitachse dar, unterscheiden sich aber in Dichte und Zweck. Eine Timeline betont den narrativen Ablauf, etwa den Status eines Bestellprozesses von der Aufgabe bis zur Zustellung, und rechnet mit wenigen, dafür inhaltlich ausführlichen Ereignissen. Ein Activity Feed dagegen protokolliert viele kleinteilige Ereignisse in kurzer Zeit, etwa jede Kommentar- oder Statusänderung in einem Projekt-Tool, und muss entsprechend kompakter und schneller scanbar sein als eine klassische Timeline.
Für das Tailwind-Styling bedeutet das zwei unterschiedliche Ausgangspunkte: Die Timeline arbeitet mit großzügigem Weißraum, deutlich sichtbaren Meilenstein-Punkten und oft mit begleitendem Fließtext oder sogar Bildern je Ereignis. Der Activity Feed dagegen reduziert jedes Ereignis auf eine einzeilige oder zweizeilige Kernaussage mit Zeitstempel, damit auch zwanzig oder mehr Einträge auf einen Blick überflogen werden können. Beide Varianten teilen sich aber dasselbe strukturelle Grundgerüst aus vertikaler Linie, Punkten und Inhaltsblock, das im nächsten Abschnitt aufgebaut wird.
2. Die vertikale Linie mit Punkten aufbauen
Das strukturelle Grundelement jeder Timeline ist eine durchgehende vertikale Linie, an der die einzelnen Ereignis-Punkte aufgereiht sind. Mit Tailwind lässt sich das ohne Pseudo-Elemente über ein einfaches Flexbox-Layout pro Zeile umsetzen: Eine linke Spalte fester Breite enthält Punkt und Linie, eine rechte Spalte nimmt den Inhalt auf. Die Linie selbst ist ein schmales div mit w-px bg-slate-200, das sich per absolute-Positionierung über die volle Höhe der linken Spalte erstreckt, während der Punkt als kleiner, abgerundeter Kreis mit rounded-full darüber liegt.
Damit die Linie optisch durchgehend wirkt und nicht an jedem Ereignis unterbrochen aussieht, muss sie über die gesamte Höhe des Elternelements laufen, auch durch den Bereich, in dem der nächste Punkt sitzt, und wird von diesem einfach optisch überdeckt. Beim letzten Eintrag der Liste sollte die Linie enden, bevor der Punkt beginnt, sonst hängt ein optisch verwirrender Linienrest unterhalb des letzten Ereignisses in der Luft. Das lässt sich am einfachsten über ein :last-child-Selektor-Aequivalent in Tailwind mit der Gruppen-Utility last:hidden auf einem separaten Linien-Element pro Zeile lösen.
<ol class="relative">
<li class="relative flex gap-4 pb-8 last:pb-0">
<!-- Linke Spalte: Punkt + Linie -->
<div class="relative flex w-8 flex-none flex-col items-center">
<span class="z-10 flex h-8 w-8 items-center justify-center rounded-full
bg-sky-500 text-white ring-4 ring-white dark:ring-slate-900">
<!-- Icon hier -->
</span>
<span class="absolute top-8 bottom-0 w-px bg-slate-200
dark:bg-slate-700 last:hidden"></span>
</div>
<!-- Rechte Spalte: Inhalt -->
<div class="flex-1 pt-1">
<p class="text-sm font-medium text-slate-900 dark:text-slate-100">
Bestellung wurde versandt
</p>
<time class="text-xs text-slate-400">vor 2 Stunden</time>
</div>
</li>
</ol>
3. Icon-Badges pro Ereignistyp
Der Punkt an der Timeline-Linie ist die ideale Stelle, um den Ereignistyp visuell zu codieren, statt ihn nur textlich zu beschreiben. Ein großzügig dimensionierter Kreis von etwa 32 Pixeln mit einem kleinen Icon in der Mitte und einer typspezifischen Hintergrundfarbe reicht in der Regel aus, um den Ereignistyp auf einen Blick zu erkennen, etwa ein Häkchen für abgeschlossene Schritte, ein Uhrensymbol für ausstehende und ein Warndreieck für fehlgeschlagene Ereignisse. Wichtig ist ein weißer oder farbiger Ring um jeden Punkt, meist mit ring-4 ring-white, der den Punkt optisch von der darunterliegenden Linie abhebt, da beide sonst nahtlos ineinander übergehen würden.
Die Farbpalette der Badges sollte sich strikt an ein festes Set halten, etwa grün für erfolgreiche, gelb oder amber für wartende, rot für fehlgeschlagene und ein neutrales Blau oder Grau für informative Ereignisse. Diese Farbcodierung darf niemals die einzige Informationsquelle sein: Das Icon selbst und ein begleitender Text müssen dieselbe Information tragen, damit auch Nutzer mit Farbfehlsichtigkeit den Ereignistyp korrekt erkennen können. Bei sehr vielen unterschiedlichen Ereignistypen lohnt sich eine zentrale Zuordnungstabelle im Code, die Typ, Icon und Farbe an einer Stelle definiert, statt diese Zuordnung an jeder Stelle im Template neu zu wiederholen.
4. Responsives Verhalten bei langen Beschreibungstexten
Sobald ein Ereignis nicht nur eine kurze Statuszeile, sondern einen längeren Beschreibungstext enthält, etwa einen vollständigen Kommentar in einem Aktivitäts-Feed, darf das Layout nicht mehr starr auf eine feste Zeilenhöhe pro Eintrag setzen. Der Inhaltsblock rechts der Linie bekommt dafür eine flexible Höhe, während die linke Spalte mit Punkt und Linie unabhängig davon exakt auf die tatsächliche Höhe des jeweiligen Eintrags reagieren muss, sonst entsteht bei unterschiedlich langen Einträgen eine visuell unsauber wirkende Linie mit ungleichmäßigen Abständen zwischen den Punkten.
Auf schmalen Bildschirmen wird zusätzlich der verfügbare horizontale Platz für den Text knapp, besonders wenn zusätzlich noch ein Avatar-Bild oder ein Zeitstempel in derselben Zeile Platz beanspruchen. Mit Tailwinds flex-wrap auf dem Header-Bereich eines Eintrags lassen sich Name, Aktion und Zeitstempel auf schmalen Bildschirmen automatisch in zwei Zeilen umbrechen, statt sie durch ein hartes overflow-hidden abzuschneiden. Lange Freitexte selbst sollten grundsätzlich mit break-words versehen werden, damit einzelne lange Wörter, etwa URLs in einem Kommentar, das Layout nicht über die verfügbare Breite hinaus sprengen.
5. Kompakte Aktivitäts-Liste versus ausführliche Timeline
Eine kompakte Activity-Liste reduziert jeden Eintrag auf das absolute Minimum: einen kleinen Punkt ohne eigenes Icon, eine einzeilige Kernaussage und einen relativen Zeitstempel am rechten Rand. Der vertikale Abstand zwischen den Einträgen fällt entsprechend gering aus, meist nicht mehr als py-2, damit möglichst viele Ereignisse ohne Scrollen sichtbar sind. Diese Variante eignet sich für Kontexte, in denen Nutzer schnell einen Ueberblick über viele Ereignisse gewinnen wollen, etwa in einer Seitenleiste oder einem Dashboard-Widget.
Die ausführliche Timeline-Ansicht dagegen investiert bewusst mehr Platz pro Ereignis: größere Icon-Badges, ein deutlicherer Ereignistitel, ein optionaler Beschreibungstext und teilweise sogar begleitende Bilder oder Dateianhänge. Der vertikale Abstand zwischen den Ereignissen wird hier großzügiger gewählt, oft pb-8 oder mehr, damit jedes Ereignis als eigenständiger, klar abgegrenzter Block wahrgenommen wird. Diese Variante passt zu Kontexten, in denen der Verlauf selbst die zentrale Information ist, etwa eine Bestellhistorie oder ein Projektfortschritt, den ein Nutzer nachvollziehen und nicht nur überfliegen soll.
6. Zeitstempel: relative Zeit versus absolutes Datum
Zeitstempel in Timelines werden meist relativ dargestellt, etwa 'vor 3 Stunden' oder 'gestern', weil sich das schneller einordnen lässt als ein absolutes Datum. Wichtig ist dabei, das absolute Datum trotzdem zugänglich zu halten, meist über das title-Attribut des <time>-Elements oder einen Tooltip bei Hover, damit Nutzer bei Bedarf den exakten Zeitpunkt nachschlagen können, ohne dass die kompakte relative Darstellung dafür weichen muss. Rein visuell bekommt der Zeitstempel eine deutlich gedämpftere Farbe als der eigentliche Ereignistext, meist text-slate-400, da er zwar wichtig, aber klar nachrangig gegenüber dem eigentlichen Inhalt ist.
Bei längeren Timelines, die sich über mehrere Tage oder Wochen erstrecken, verliert eine rein relative Zeitangabe schnell an Präzision, da 'vor 5 Tagen' weniger konkret ist als ein Datum. Hier bietet sich ein hybrider Ansatz an: Ereignisse der letzten 24 Stunden bekommen eine relative Angabe, ältere Ereignisse werden mit einem festen Datum im Format Tag und Monat dargestellt. Diese Umschaltung sollte konsistent an einer zentralen Stelle in der Formatierungslogik erfolgen, nicht durch mehrfach dupliziertes Markup mit bedingter Anzeige an verschiedenen Stellen im Template.
7. Gruppierung nach Tagen mit eigenen Datums-Headern
Sobald ein Activity Feed sich über mehrere Tage erstreckt, hilft eine Gruppierung nach Kalendertag deutlich beim Scannen der Liste, ähnlich wie Chat-Anwendungen Nachrichten nach Tagen gruppieren. Ein Datums-Header, etwa 'Heute', 'Gestern' oder ein konkretes Datum, unterbricht die durchgehende vertikale Linie an dieser Stelle bewusst und bekommt eine eigene, leicht abgesetzte Formatierung mit sticky top-0, damit er beim Scrollen innerhalb der Gruppe sichtbar bleibt und der Nutzer jederzeit weiß, welchen Tag er gerade betrachtet.
Die Timeline-Linie selbst pausiert sinnvollerweise an jedem Tages-Header und beginnt darunter neu, statt visuell über die Trennung hinwegzulaufen, da eine durchgehende Linie über mehrere Tagesgruppen hinweg den Eindruck einer einzigen zusammenhängenden Sequenz erweckt, obwohl es sich eigentlich um separate Tagesabschnitte handelt. Farblich bekommt der Datums-Header meist einen dezent abgesetzten Hintergrund, etwa bg-slate-50, um ihn klar von den eigentlichen Ereignis-Einträgen abzugrenzen, ohne dabei visuell zu dominant zu wirken.
8. Statusbasierte Farbcodierung über die gesamte Timeline
Neben der Farbe des einzelnen Icon-Badges lohnt es sich, bei prozessorientierten Timelines, etwa einem Bestellverlauf, auch die Linie selbst statusabhängig einzufärben. Abgeschlossene Abschnitte der Linie zwischen zwei bereits erreichten Meilensteinen bekommen eine kräftige Farbe wie bg-emerald-500, während der Abschnitt zwischen dem letzten erreichten und dem nächsten, noch ausstehenden Meilenstein grau bleibt. Das erzeugt auf einen Blick den Eindruck eines Fortschrittsbalkens, der in die Timeline integriert ist, ohne dass dafür ein separates Fortschritts-Element nötig wäre.
Wichtig ist dabei, die Farbübergänge nicht abrupt an einem einzelnen Pixel enden zu lassen, sondern den Farbwechsel konsequent an der Position des jeweiligen Punktes vorzunehmen, damit die visuelle Grenze zwischen erledigt und ausstehend exakt mit dem entsprechenden Meilenstein-Icon zusammenfällt. Bei einer fehlgeschlagenen oder abgebrochenen Aktion in der Mitte eines Prozesses sollte die Linie ab diesem Punkt in einer Warnfarbe wie bg-red-400 weiterlaufen, damit sofort erkennbar ist, dass der weitere Ablauf vom Normalfall abweicht.
9. Barrierefreiheit: Semantik statt reiner Optik
Eine Timeline sollte semantisch als geordnete Liste mit <ol> ausgezeichnet werden, da die chronologische Reihenfolge der Ereignisse eine inhaltliche Bedeutung trägt, die eine ungeordnete Liste nicht transportieren würde. Jedes Ereignis-Icon, das ausschließlich dekorativ neben einem bereits vorhandenen Textlabel steht, bekommt aria-hidden="true", damit Screenreader es nicht redundant vorlesen, während Icons, die die einzige Informationsquelle für den Ereignistyp sind, zwingend ein aria-label mit der textuellen Beschreibung des Status benötigen.
Der relative Zeitstempel sollte immer in ein semantisches <time datetime="...">-Element mit dem maschinenlesbaren ISO-Datum eingebettet werden, auch wenn die sichtbare Beschriftung nur 'vor 2 Stunden' lautet, damit Screenreader und andere Werkzeuge den exakten Zeitpunkt korrekt interpretieren können. Bei interaktiven Timelines, in denen einzelne Ereignisse aufklappbar sind, muss der Fokus-Zustand des klickbaren Bereichs deutlich sichtbar sein, meist über einen Tailwind-Fokus-Ring, da die Timeline sonst für reine Tastaturnutzer praktisch unbedienbar wird.
| Ereignistyp | Icon-Farbe | Typische Verwendung | Linienfarbe danach |
|---|---|---|---|
| Erfolgreich | bg-emerald-500 | Abgeschlossener Schritt, bestätigte Aktion | bg-emerald-500 |
| Ausstehend | bg-slate-300 | Noch nicht erreichter Meilenstein | bg-slate-200 |
| Warnung | bg-amber-500 | Aktion erfordert Aufmerksamkeit, aber kein Abbruch | bg-amber-400 |
| Fehlgeschlagen | bg-red-500 | Abgebrochene oder fehlgeschlagene Aktion | bg-red-400 |
| Information | bg-sky-500 | Rein informatives Ereignis ohne Statusänderung | bg-slate-200 |
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
Timeline- und Activity-Feed-Komponenten mit Tailwind: Das Wichtigste auf einen Blick
Grundgerüst
Zwei-Spalten-Layout aus Punkt-plus-Linie links und Inhaltsblock rechts, Linie endet vor dem letzten Punkt.
Icon-Badges
Farbe, Icon und Text tragen dieselbe Information redundant, niemals Farbe allein als Statusquelle.
Kompakt vs. ausführlich
Activity-Liste minimiert Abstand und Inhalt pro Eintrag, Timeline investiert bewusst mehr Platz je Ereignis.
Barrierefreiheit
Geordnete Liste, aria-label für reine Icon-Information, time-Element mit maschinenlesbarem Datum.