Formular-Wizard mit Schritt-Indikator gestalten
AI generated
</>
tw
Tailwind CSS · UI-Komponenten · Utility-First · Design Patterns
Formular-Wizard mit Schritt-Indikator gestalten
Orientierung für mehrstufige Formulare

Ein guter Schritt-Indikator zeigt jederzeit, wo im Formular-Wizard man sich befindet, welche Schritte bereits erledigt sind und wie viele noch folgen. Mit Tailwind CSS und Alpine.js lässt sich dieser Indikator konsequent aus wenigen wiederverwendbaren Zuständen aufbauen, statt für jeden Schritt eigenes Markup zu pflegen.

17 Min. Lesezeit Schritt-Indikator · Alpine.js · Validierung · Barrierefreiheit Tailwind CSS v4 · alle modernen Browser

1. Warum ein Schritt-Indikator den Wizard trägt

Ein mehrstufiges Formular ohne sichtbaren Schritt-Indikator fühlt sich für Nutzer wie ein Blindflug an. Ohne die Information, wie viele Schritte insgesamt folgen, entsteht schnell der Eindruck, ein Formular-Wizard könnte endlos lang sein, was die Abbruchrate messbar erhöht. Ein gut gestalteter Schritt-Indikator löst genau dieses Problem, indem er Fortschritt sichtbar macht, bevor eine einzige Eingabe getätigt wurde.

Technisch betrachtet ist ein Schritt-Indikator eine reine Zustandsmaschine mit visueller Repräsentation, jeder Schritt befindet sich entweder im Zustand abgeschlossen, aktiv oder noch ausstehend. Diese drei Zustände lassen sich mit Tailwind CSS über bedingte Klassen abbilden, während Alpine.js die eigentliche Navigationslogik übernimmt. Die folgenden Abschnitte bauen einen vollständigen Schritt-Indikator für einen Formular-Wizard auf, von der Grundstruktur bis zur vollständigen Barrierefreiheit.

2. Grundstruktur: HTML für den Schritt-Indikator

Die Grundstruktur eines Schritt-Indikators besteht aus einer geordneten Liste, in der jeder Listeneintrag einen Kreis mit Nummer oder Icon sowie ein Label enthält. Eine ol-Liste ist semantisch passender als div-Elemente, da sie die inhärente Reihenfolge der Schritte transportiert, auch ohne zusätzliches ARIA. Zwischen den Kreisen sitzt eine Verbindungslinie, die den bereits zurückgelegten Fortschritt farblich hervorhebt.

Für einen Formular-Wizard mit vier Schritten reicht ein einfaches Grid- oder Flex-Layout mit gleichmäßiger Verteilung. Wichtig ist, dass jeder Schritt im Schritt-Indikator als eigenständiges, klickbares Element markiert wird, sofern das Springen zu bereits abgeschlossenen Schritten erlaubt sein soll. Zukünftige, noch nicht erreichte Schritte sollten dagegen nicht anklickbar sein, um Nutzer nicht zu Schritten springen zu lassen, deren Voraussetzungen noch fehlen.


<!-- Base structure for a four-step wizard indicator -->
<ol class="flex items-center w-full mb-10">
  <li class="flex w-full items-center text-sky-600 after:content-[''] after:w-full after:h-0.5 after:border-b after:border-sky-600 after:border-4 after:inline-block">
    <span class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-sky-600 text-white font-bold">
      <svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"/></svg>
    </span>
  </li>
  <li class="flex w-full items-center text-sky-600 after:content-[''] after:w-full after:h-0.5 after:border-b after:border-slate-200 after:border-4 after:inline-block">
    <span class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full border-2 border-sky-600 bg-white text-sky-600 font-bold">2</span>
  </li>
  <li class="flex w-full items-center text-slate-400 after:content-[''] after:w-full after:h-0.5 after:border-b after:border-slate-200 after:border-4 after:inline-block">
    <span class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full border-2 border-slate-200 bg-white text-slate-400 font-bold">3</span>
  </li>
  <li class="flex items-center text-slate-400">
    <span class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full border-2 border-slate-200 bg-white text-slate-400 font-bold">4</span>
  </li>
</ol>

3. Zustände stylen: aktiv, abgeschlossen, zukünftig

Jeder Zustand im Schritt-Indikator braucht eine klar unterscheidbare visuelle Sprache. Der abgeschlossene Zustand nutzt eine gefüllte Kreisfläche mit Akzentfarbe und ein Häkchen-Icon statt einer Nummer, das signalisiert unmissverständlich Erledigung. Der aktive Zustand nutzt denselben Farbton, aber als Umrandung statt Füllung, kombiniert mit einer fetteren Schrift für das Label darunter. Zukünftige Schritte bleiben in neutralem Grau, um klar von den bereits relevanten Schritten abzugrenzen.

Ein häufiger Gestaltungsfehler ist zu geringer Kontrast zwischen aktivem und zukünftigem Zustand, was den Schritt-Indikator auf einen Blick unlesbar macht. Die Kombination aus Farbe, Füllung und Icon-Wechsel sorgt dafür, dass der Zustand auch für Nutzer mit eingeschränktem Farbsehen erkennbar bleibt, denn Farbe allein sollte nie das einzige Unterscheidungsmerkmal sein.

4. Verbindungslinien zwischen den Schritten

Die Verbindungslinie zwischen zwei Kreisen im Schritt-Indikator transportiert eine zusätzliche Information, nämlich ob der Übergang zwischen zwei Schritten bereits vollständig zurückgelegt wurde. Mit dem Tailwind-Pseudo-Element-Utility after: lässt sich diese Linie ohne zusätzliches Markup direkt an das li-Element anhängen, was die Struktur schlank hält.

Für einen sauberen Übergang sollte die Linienfarbe exakt zum Zustand des vorherigen Schritts passen, nicht zum nachfolgenden. Eine Linie zwischen einem abgeschlossenen und einem aktiven Schritt im Schritt-Indikator sollte also vollständig in der Akzentfarbe erscheinen, während eine Linie zwischen aktivem und zukünftigem Schritt in neutralem Grau bleibt. Diese Feinheit macht den Unterschied zwischen einem technisch korrekten und einem wirklich durchdachten Indikator.


/* Connector line styling via Tailwind after: pseudo-element utilities */
.step-connector {
  /* Applied conditionally based on step state */
}

/* Completed connector: full accent color */
.step-connector--done::after {
  border-color: theme(colors.sky.600);
}

/* Pending connector: neutral gray */
.step-connector--pending::after {
  border-color: theme(colors.slate.200);
}

/* Equivalent Tailwind classes applied conditionally with Alpine :class bindings:
   after:border-sky-600   -> completed transition
   after:border-slate-200 -> pending transition */

5. Alpine.js State für die Wizard-Navigation

Die eigentliche Logik hinter einem Schritt-Indikator ist überraschend kompakt. Ein einzelner currentStep-Wert in einer Alpine.js-Komponente reicht aus, um alle drei Zustände für jeden Schritt zu berechnen, ohne dass jeder Schritt seinen eigenen Zustand separat verwalten muss. Ein Schritt gilt als abgeschlossen, wenn seine Nummer kleiner ist als currentStep, als aktiv, wenn beide gleich sind, und als zukünftig in allen anderen Fällen.

Diese zentrale Zustandsverwaltung macht den Schritt-Indikator trivial erweiterbar. Ein fünfter oder sechster Schritt bedeutet lediglich ein weiteres Listenelement mit derselben bedingten Klassenlogik, keine zusätzliche JavaScript-Logik. Für das Springen zu bereits abgeschlossenen Schritten reicht ein Klick-Handler, der currentStep direkt auf die Zielnummer setzt, sofern diese kleiner als der aktuelle Wert ist.


<!-- Alpine.js component computing step state from a single currentStep value -->
<div x-data="{
  currentStep: 2,
  totalSteps: 4,
  stepState(n) {
    if (n < this.currentStep) return 'done';
    if (n === this.currentStep) return 'active';
    return 'pending';
  }
}">
  <ol class="flex items-center w-full mb-10">
    <template x-for="n in totalSteps" :key="n">
      <li
        class="flex w-full items-center"
        :class="{
          'text-sky-600': stepState(n) !== 'pending',
          'text-slate-400': stepState(n) === 'pending'
        }"
      >
        <button
          type="button"
          @click="if (stepState(n) === 'done') currentStep = n"
          class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full font-bold"
          :class="{
            'bg-sky-600 text-white': stepState(n) === 'done',
            'border-2 border-sky-600 bg-white text-sky-600': stepState(n) === 'active',
            'border-2 border-slate-200 bg-white text-slate-400': stepState(n) === 'pending'
          }"
          x-text="stepState(n) === 'done' ? '' : n"
        ></button>
      </li>
    </template>
  </ol>
</div>

6. Validierung pro Schritt vor dem Weiterklicken

Ein Schritt-Indikator, der Vorwärtsspringen erlaubt, ohne die Eingaben des aktuellen Schritts zu prüfen, führt schnell zu unvollständigen Formularen. Die saubere Lösung ist eine Validierungsfunktion pro Schritt, die vor dem Inkrementieren von currentStep aufgerufen wird. Schlägt die Validierung fehl, bleibt der Wizard auf dem aktuellen Schritt und zeigt eine Fehlermeldung direkt am betroffenen Feld an.

Für den Formular-Wizard bedeutet das: Der Weiter-Button ruft nicht direkt currentStep++ auf, sondern eine Methode goNext(), die zunächst validateStep(currentStep) prüft. Nur bei erfolgreicher Validierung wird der Schritt-Indikator tatsächlich weitergeschaltet. Diese Trennung von Navigation und Validierung hält die Komponente testbar, da beide Aspekte unabhängig voneinander geprüft werden können.

7. Responsive Anpassung: Mobile vs. Desktop

Auf schmalen Bildschirmen wird ein horizontaler Schritt-Indikator mit vollständigen Textlabels schnell zu eng, besonders bei fünf oder mehr Schritten. Eine bewährte Lösung ist, die Labels unterhalb von sm: komplett auszublenden und nur die nummerierten Kreise mit der aktuellen Schritt-Position als Text darüber zu zeigen, etwa Schritt 2 von 4. Diese kompaktere Variante bleibt auf jedem Bildschirm lesbar, ohne horizontales Scrollen zu erzwingen.

Für sehr lange Wizards mit sechs oder mehr Schritten empfiehlt sich zusätzlich ein reiner Fortschrittsbalken als mobile Alternative zum vollständigen Schritt-Indikator, der auf Desktop-Breakpoints sichtbar bleibt. Tailwinds hidden sm:flex-Kombination wechselt zwischen beiden Darstellungen, ohne dass zwei getrennte Komponenten gepflegt werden müssen.


<!-- Mobile: compact progress text, Desktop: full step indicator -->
<div class="sm:hidden mb-6 text-sm font-semibold text-slate-600">
  Schritt <span x-text="currentStep"></span> von <span x-text="totalSteps"></span>
  <div class="mt-2 h-1.5 w-full rounded-full bg-slate-200">
    <div
      class="h-1.5 rounded-full bg-sky-600 transition-all"
      :style="`width: ${(currentStep / totalSteps) * 100}%`"
    ></div>
  </div>
</div>
<ol class="hidden sm:flex items-center w-full mb-10">
  <!-- Full step indicator markup, hidden below sm: breakpoint -->
</ol>

8. Barrierefreiheit: aria-current und Screenreader

Ein rein visuell korrekter Schritt-Indikator bleibt für Screenreader-Nutzer bedeutungslos, wenn keine ARIA-Semantik ergänzt wird. Das aria-current="step"-Attribut am aktiven Listeneintrag ist der wichtigste Baustein, es teilt Screenreadern mit, welcher Schritt gerade aktiv ist, unabhängig von der visuellen Darstellung. Abgeschlossene Schritte sollten zusätzlich über einen versteckten Text mit sr-only-Klasse als erledigt gekennzeichnet werden, da das Häkchen-Icon allein nicht vorgelesen wird.

Für den gesamten Schritt-Indikator empfiehlt sich außerdem ein umschließendes nav-Element mit aria-label="Formular-Fortschritt", damit Screenreader-Nutzer die Navigation klar von anderem Seiteninhalt unterscheiden können. Klickbare Schritte, die zu bereits abgeschlossenen Abschnitten zurückführen, sollten als echte button-Elemente markiert sein, niemals als reine div-Elemente mit Klick-Handler, da sonst die native Tastaturbedienbarkeit verloren geht.

9. Horizontale vs. vertikale Wizard-Muster

Neben dem horizontalen Standardlayout existiert für lange Formulare mit vielen Detailschritten auch das vertikale Muster, bei dem der Schritt-Indikator an der Seite steht und der Inhalt darunter oder daneben in einer Spalte fließt. Beide Muster haben spezifische Stärken, die sich am besten in direktem Vergleich zeigen lassen.

Kriterium Horizontaler Indikator Vertikaler Indikator
Ideale Schrittanzahl 3 bis 5 Schritte 6 oder mehr Schritte
Mobile Eignung Braucht kompakte Variante unterhalb sm: Meist direkt in horizontale Variante gewandelt
Platzbedarf Wenig vertikaler Platz Braucht Seitenspalte, mehr horizontaler Platz
Label-Länge Kurze Labels bevorzugt Auch längere Beschreibungstexte möglich

Für die meisten Formular-Wizards mit vier bis fünf Schritten ist die horizontale Variante die pragmatischere Wahl, weil sie ohne zusätzliche Seitenspalte auskommt und auf Mobilgeräten leichter zu einer kompakten Fortschrittsanzeige reduziert werden kann. Der Schritt-Indikator in vertikaler Form lohnt sich vor allem bei komplexen Konfiguratoren, in denen jeder Schritt eine eigene, ausführlichere Beschreibung neben dem Kreis-Icon braucht.

Mironsoft

Tailwind CSS Komponenten und Design Systeme

Formular-Wizards, die Nutzer wirklich zu Ende führen?

Wir gestalten mehrstufige Formulare mit klarem Schritt-Indikator, sauberer Validierung pro Schritt und vollständiger Barrierefreiheit, um Abbruchraten in euren Checkout- und Onboarding-Flows spürbar zu senken.

UX-Audit

Bestehende Wizards auf Orientierung und Abbruchpunkte prüfen

Komponenten-Bau

Schritt-Indikator mit Alpine.js State und Validierung umsetzen

Barrierefreiheit

aria-current und Screenreader-Test für den gesamten Wizard

10. Zusammenfassung

Ein durchdachter Schritt-Indikator ist kein reines Dekorationselement, sondern ein zentrales Orientierungswerkzeug für jeden Formular-Wizard. Die drei Zustände abgeschlossen, aktiv und zukünftig lassen sich mit wenigen Tailwind-Klassen klar unterscheidbar gestalten, während eine einzige currentStep-Variable in Alpine.js sämtliche Zustandsberechnungen übernimmt. Verbindungslinien zwischen den Kreisen transportieren zusätzlichen Fortschrittskontext, ohne zusätzliches Markup zu benötigen.

Validierung pro Schritt verhindert, dass Nutzer mit unvollständigen Daten vorwärtsspringen, während die responsive Umschaltung zwischen vollständigem Schritt-Indikator und kompaktem Fortschrittsbalken die Komponente auch auf kleinen Bildschirmen benutzbar hält. aria-current="step" und ein umschließendes nav-Element sorgen dafür, dass die gesamte Navigation auch mit Screenreader vollständig nachvollziehbar bleibt.

Formular-Wizard Schritt-Indikator — Das Wichtigste auf einen Blick

Zustände

Abgeschlossen, aktiv und zukünftig klar über Farbe, Füllung und Icon unterscheiden, nicht nur über Farbe allein.

Zustandsverwaltung

Eine zentrale currentStep-Variable in Alpine.js berechnet alle Schrittzustände, statt separater Flags.

Validierung

Weiterschalten nur nach erfolgreicher Validierung des aktuellen Schritts, getrennt von der reinen Navigation.

Barrierefreiheit

aria-current="step", sr-only-Texte für erledigte Schritte und echte Button-Elemente für Navigation.

11. FAQ: Formular-Wizard und Schritt-Indikator

1Maximale Schrittanzahl?
Drei bis fünf Schritte ideal, ab sechs vertikale oder kompakte Fortschrittsanzeige erwägen.
2Rücksprung zu Schritten erlauben?
Ja, nur bei abgeschlossenen Schritten. Zukünftige Schritte bleiben deaktiviert.
3Weiterklicken ohne vollständige Daten verhindern?
Validierungsfunktion pro Schritt vor dem Inkrementieren von currentStep aufrufen.
4Mobiles Verhalten?
Kompakte Textanzeige mit Fortschrittsbalken unterhalb der sm:-Grenze.
5Wichtiges ARIA-Attribut?
aria-current="step" am aktiven Listeneintrag.
6Reicht Farbe zur Unterscheidung?
Nein, Icon-Wechsel und Füllung immer als zusätzliches Merkmal ergänzen.
7Verbindungslinien umsetzen?
Über das Tailwind after:-Utility direkt am li-Element, Farbe je nach Vorgänger-Zustand.
8Vertikal statt horizontal?
Ab sechs Schritten oder bei längeren Beschreibungstexten je Schritt.
9Wie viele Zustände nötig?
Drei: abgeschlossen, aktiv, zukünftig, berechnet aus einer einzigen currentStep-Variable.
10div oder button für klickbare Schritte?
Immer button, für native Tastaturbedienbarkeit ohne zusätzliche Logik.