CSS Zähler

Zuletzt aktualisiert am 15. Februar 2026

CSS Zähler ermöglichen automatische Nummerierung ohne HTML-Listen. Mit counter-reset erzeugst du einen Zähler, mit counter-increment zählst du ihn hoch, und mit den Funktionen counter() und counters() gibst du den Wert über die content-Eigenschaft aus. So kannst du Überschriften, Abschnitte, Schritte oder beliebige Elemente durchnummerieren, ohne die Nummern manuell im HTML zu pflegen. Besonders mächtig wird es mit counters() für verschachtelte Nummerierungen wie 1.1, 1.2, 2.1.

Syntax
counter-reset: <name> <integer>?
Initialwert
none
Vererbt
Nein
Animierbar
Nein

Grundlagen

CSS Zähler bestehen aus drei Teilen, die zusammenspielen:

  1. counter-reset erstellt einen neuen Zähler und setzt ihn auf einen Startwert (Standard: 0). Du setzt counter-reset auf das Elternelement, das den Zählbereich definiert.
  2. counter-increment erhöht den Zähler um einen Wert (Standard: 1). Du setzt es auf die Elemente, die gezählt werden sollen.
  3. counter() / counters() sind Funktionen, die du in content verwendest, um den aktuellen Zählerwert auszugeben. counter() gibt einen einzelnen Wert aus, counters() sammelt alle verschachtelten Instanzen desselben Zählers mit einem Trennzeichen.

Ein typisches Beispiel: Du setzt counter-reset: section auf den <body>, counter-increment: section auf jedes <h2>, und content: counter(section) ". " auf h2::before. Schon werden alle <h2> automatisch durchnummeriert, und die Nummern aktualisieren sich automatisch, wenn du einen Abschnitt hinzufügst, entfernst oder umstellst.

Syntax & Werte

counter-reset

Wert Beschreibung Beispiel
none Kein Zähler wird erstellt oder zurückgesetzt (Standard). counter-reset: none
<name> Erstellt den Zähler mit dem Startwert 0. counter-reset: section
<name> <integer> Erstellt den Zähler mit einem bestimmten Startwert. counter-reset: section 5
<name1> <name2> Mehrere Zähler gleichzeitig erstellen. counter-reset: section step

counter-increment

Wert Beschreibung Beispiel
none Kein Zähler wird erhöht (Standard). counter-increment: none
<name> Erhöht den Zähler um 1. counter-increment: section
<name> <integer> Erhöht den Zähler um den angegebenen Wert. Negative Werte zählen rückwärts. counter-increment: section 2

counter() und counters()

Wert Beschreibung Beispiel
counter(name) Gibt den aktuellen Wert des Zählers als Dezimalzahl aus. content: counter(section)
counter(name, style) Gibt den Wert im angegebenen Zählstil aus (z.B. upper-roman, lower-alpha). content: counter(section, upper-roman)
counters(name, string) Sammelt alle verschachtelten Instanzen des Zählers mit einem Trennzeichen. content: counters(section, ".")
counters(name, string, style) Verschachtelte Zähler mit Trennzeichen und Zählstil. content: counters(section, ".", upper-roman)

Beispiele

Automatische Abschnittsnummern

Überschriften automatisch durchnummerieren, ohne die Nummern im HTML zu schreiben.

Automatische Abschnittsnummern
body {
  counter-reset: abschnitt;
}

h2 {
  counter-increment: abschnitt;
}

h2::before {
  content: counter(abschnitt) ". ";
  color: #3b82f6;
}

Eigene nummerierte Liste

Eine optisch ansprechende nummerierte Liste mit großen, farbigen Nummern, ganz ohne <ol>.

Custom nummerierte Liste
.list {
  counter-reset: item;
}

.list-item {
  counter-increment: item;
}

.list-item::before {
  content: counter(item);
  background: #3b82f6;
  color: #fff;
  border-radius: 50%;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
}

Verschachtelte Nummerierung

Mit counters() erzeugst du verschachtelte Nummerierungen wie 1.1, 1.2, 2.1. Jede neue Verschachtelungsebene erstellt eine eigene Instanz des gleichen Zählers.

Verschachtelte Nummerierung mit counters()
ol {
  counter-reset: nested;
  list-style: none;
}

li {
  counter-increment: nested;
}

li::before {
  content: counters(nested, ".") " ";
  color: #3b82f6;
  font-weight: 700;
}

Verschiedene Zählstile

counter() akzeptiert als zweites Argument einen Zählstil. Damit kannst du römische Zahlen, Buchstaben oder andere Systeme verwenden.

Verschiedene Zählstile
/* Römische Zahlen */
li::before { content: counter(c, upper-roman) ". "; }

/* Kleinbuchstaben */
li::before { content: counter(c, lower-alpha) ") "; }

/* Führende Null */
li::before { content: counter(c, decimal-leading-zero) " "; }

Schritt-für-Schritt Anleitung

CSS Zähler funktionieren auf beliebigen Elementen, nicht nur auf Listen. Hier werden <div>-Elemente als Schritte durchnummeriert.

Schritt-für-Schritt Anleitung mit Counter
.tutorial {
  counter-reset: step;
}

.step {
  counter-increment: step;
}

.step::before {
  content: counter(step);
  background: linear-gradient(135deg, #3b82f6, #7c3aed);
  color: #fff;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
}

Barrierefreiheit

Inhalte, die über ::before und content generiert werden, erscheinen nicht im DOM und sind für manche assistive Technologien nicht zugänglich. Screenreader lesen content-Text zwar inzwischen meist vor, aber das Verhalten ist nicht einheitlich. Verlasse dich daher nicht darauf, dass die generierten Nummern von allen Nutzern wahrgenommen werden.

Wenn die Nummerierung semantische Bedeutung hat (z.B. eine geordnete Reihenfolge), verwende <ol> statt CSS-Counter. <ol> vermittelt die Reihenfolge semantisch korrekt an Screenreader, während CSS-Counter rein visuell sind. CSS Zähler eignen sich besser für dekorative Nummerierungen, bei denen die Nummer eine optische Ergänzung ist, aber kein essentieller Inhalt.

Für Dokumentstrukturen wie Kapitel- und Abschnittsnummern sollte die Hierarchie über eine korrekte Heading-Struktur (<h1> bis <h6>) vermittelt werden, nicht allein über CSS-Counter. Die Counter-Nummern sind dann eine visuelle Hilfe, aber die eigentliche Struktur kommt aus dem HTML.

Häufige Fehler

  • counter-reset auf dem falschen Element: counter-reset muss auf dem Elternelement stehen, nicht auf dem Element, das gezählt wird. Setzt du counter-reset auf h2, wird der Zähler bei jedem <h2> zurückgesetzt, statt hochzuzählen.
  • counter-increment ohne counter-reset: Ohne counter-reset existiert der Zähler nicht. Der Browser erzeugt dann implizit einen Zähler, aber das Verhalten ist unzuverlässig und schwer nachzuvollziehen.
  • counter() außerhalb von content verwenden: counter() und counters() funktionieren nur innerhalb der content-Eigenschaft auf ::before oder ::after. Du kannst sie nicht direkt in Eigenschaften wie width oder color verwenden.
  • Verschachtelte Zähler ohne counter-reset pro Ebene: Bei verschachtelten Listen muss jede <ol> oder <ul> den Zähler zurücksetzen, damit jede Ebene ihren eigenen Zähler bekommt. Ohne das zählen alle Ebenen denselben Zähler weiter.
  • Reihenfolge von Increment und Content verwechseln: counter-increment wird angewendet, bevor content ausgewertet wird. Der Zähler zeigt also den bereits erhöhten Wert an. Wenn du bei 1 starten willst, setze counter-reset: name 0 (Standard), nicht counter-reset: name 1.

Browser-Kompatibilität

CSS Counter (counter-reset, counter-increment, counter(), counters()) werden seit über 20 Jahren von allen Browsern vollständig unterstützt.

ClientUnterstützungHinweise
ChromeKomplett
FirefoxKomplett
SafariKomplett
EdgeKomplett
OperaKomplett

Email-Kompatibilität

CSS Counter werden von den meisten Email-Clients nicht unterstützt, da ::before/::after und content in Emails stark eingeschränkt sind.

ClientUnterstützungHinweise
Apple MailKomplett
GmailKeinecontent und ::before/::after werden entfernt
OutlookKeineKein Support für Pseudo-Elemente oder content
ThunderbirdKomplett
Yahoo MailKeinePseudo-Elemente werden nicht unterstützt

Verwandte Eigenschaften

Bleib auf dem Laufenden

Erhalte neue Inhalte direkt in dein Postfach

Mit der Anmeldung akzeptierst du unsere Datenschutzerklärung. Du kannst dich jederzeit über den Link in den E-Mails wieder abmelden.

Was erwartet dich?

Neue Artikel & Videos

Wenn ich was Neues veröffentliche, erfährst du's hier zuerst.

Plattform & Kurs-Updates

Neue Kurse, Referenz-Updates und gelegentlich Sonderpreise zum Launch.

Einmal die Woche in deinem Postfach

Kurz, auf den Punkt, kein Spam.