🔼 CSS counter-increment — Complete Tutorial

🌐 What Is counter-increment?

The counter-increment property increases the value of a CSS counter each time an element appears. It is used together with counter-reset andcontent: counter(name) to create automatic numbering.

>>counter-increment is the engine that moves CSS counters forward.”

Note

✔ Works with pseudo-elements
✔ Can increment multiple counters
✔ Supports custom step values (e.g., +2, -1)

📦 Basic Syntax

Syntax

counter-increment: counterName optionalStep;

counterName → the name of the counter
optionalStep → default is 1 (increment by 1)

📌 1. Simple Increment Example

Simple counter

body {
  counter-reset: section;
}

h2::before {
  counter-increment: section;
  content: counter(section) ". ";
}

Each <h2> becomes auto-numbered:1. Title, 2. Title, 3. Title

📌 2. Incrementing by Custom Steps

Custom step

.counter-box {
  counter-reset: number;
}

.item::before {
  counter-increment: number 2;
  content: counter(number);
}

Counter increases by 2 each time: 2, 4, 6, 8 ...

📌 3. Decrementing a Counter

Decrement example

.reverse-list {
  counter-reset: count 10;
}

.reverse-item::before {
  counter-increment: count -1;
  content: counter(count);
}

Produces: 10, 9, 8, 7…

📌 4. Incrementing Multiple Counters

Multiple counters

body {
  counter-reset: chapter section;
}

h1::before {
  counter-increment: chapter;
  content: "Chapter " counter(chapter);
}

h2::before {
  counter-increment: section;
  content: counter(chapter) "." counter(section);
}

📌 5. Using counter-increment with Lists

Custom ordered list

ol {
  list-style: none;
  counter-reset: li;
}

li::before {
  counter-increment: li;
  content: counter(li) ") ";
}

Every <li> increments the counter automatically.

📌 6. Incrementing Inside Nested Items

Nested example

ol {
  counter-reset: level1;
}

ol > li {
  counter-increment: level1;
}

ol > li::before {
  content: counter(level1) ". ";
}

ol > li ol {
  counter-reset: level2;
}

ol > li ol > li {
  counter-increment: level2;
}

ol > li ol > li::before {
  content: counter(level1) "." counter(level2) " ";
}

📌 7. Using counter-increment with content()

Styled step display

.step::before {
  counter-increment: step;
  content: "Step " counter(step) ": ";
  font-weight: bold;
}

📘 8. Combining counter-reset & counter-increment

These two properties always work together.

Combination example

.cards {
  counter-reset: card;
}

.card::before {
  counter-increment: card;
  content: "Card #" counter(card);
}

🧪 Real-World Examples

1️⃣ Numbered Steps / Tutorial Instructions

Steps

.steps {
  counter-reset: step;
}

.step::before {
  counter-increment: step;
  content: "Step " counter(step);
}

2️⃣ Numbered FAQ Items

FAQ numbering

.faq {
  counter-reset: q;
}

.faq-item::before {
  counter-increment: q;
  content: "Q" counter(q) ": ";
}

3️⃣ Numbered Cards in a Grid

Card numbering

.grid {
  counter-reset: index;
}

.card::before {
  counter-increment: index;
  content: "#" counter(index);
  font-size: 1.5rem;
  opacity: 0.6;
}

⚠️ Common Mistakes

  • ❌ Forgetting counter-reset (counters won’t start)
  • ❌ Expecting numbers without content
  • ❌ Using counter-increment on the wrong selector
  • ❌ Incrementing the counter multiple times unintentionally

Note

✔ Always reset the counter on the container
✔ Place counter-increment on the repeating elements

🔥 Summary

The counter-increment property updates a CSS counter each time an element appears. It enables powerful auto-numbering features in pure CSS — perfect for lists, headings, steps, cards, and structured documents.

>>“Combine counter-reset + counter-increment for dynamic numbering without JavaScript.”

Learn more →MDN Docs 📘