CSS Counters

CSS counters automatically number elements. Useful for lists and custom numbering.

On this page

CSS Counters

CSS counters let you automatically number elements using CSS. They are useful for creating numbered headings, steps, lists, and nested numbering without manually writing the numbers in HTML.

Counters work with three main parts: counter-reset, counter-increment, and content with counter().

Counters

To use a counter, first reset it on a parent element, then increment it on each item, and finally display it using a pseudo-element.

.steps {
  counter-reset: step;
}

.steps li {
  counter-increment: step;
}

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

Example HTML:

<ol class="steps">
  <li>Install the tools</li>
  <li>Create a project</li>
  <li>Write your CSS</li>
</ol>

Counter Styling

You can style the counter output like a badge.

.steps {
  counter-reset: step;
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: 520px;
}

.steps li {
  counter-increment: step;
  padding: 12px 12px 12px 52px;
  border: 1px solid #eee;
  border-radius: 12px;
  margin-bottom: 10px;
  position: relative;
}

.steps li::before {
  content: counter(step);
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 28px;
  height: 28px;
  line-height: 28px;
  text-align: center;
  border-radius: 999px;
  border: 1px solid #d6e4ff;
  background: #f3f6ff;
  font-weight: bold;
  font-size: 13px;
}

Nested Counters

Nested counters are useful for numbering sections like 1, 1.1, 1.2, 2, 2.1, etc.

Reset the inner counter inside each parent item, then increment both levels as needed.

.outline {
  counter-reset: section;
  list-style: none;
  padding: 0;
  margin: 0;
}

.outline > li {
  counter-increment: section;
  margin-bottom: 10px;
}

.outline > li::before {
  content: counter(section) ". ";
  font-weight: bold;
}

.outline ul {
  counter-reset: sub;
  list-style: none;
  padding-left: 22px;
  margin: 8px 0 0;
}

.outline ul li {
  counter-increment: sub;
  margin-bottom: 6px;
}

.outline ul li::before {
  content: counter(section) "." counter(sub) " ";
  color: #555;
  font-weight: 600;
}

Example HTML:

<ul class="outline">
  <li>Getting Started
    <ul>
      <li>Install</li>
      <li>First Page</li>
    </ul>
  </li>

  <li>Basics
    <ul>
      <li>Selectors</li>
      <li>Box Model</li>
    </ul>
  </li>
</ul>

Code Challenge

Goal: Build a numbered “steps” list using CSS counters, and add a nested outline using nested counters.

HTML:

<ol class="steps">
  <li>Plan the layout</li>
  <li>Write the CSS</li>
  <li>Test on mobile</li>
</ol>

<ul class="outline">
  <li>Section
    <ul>
      <li>Sub item</li>
      <li>Sub item</li>
    </ul>
  </li>
</ul>

Task:

  • Remove default list styles
  • Use counter-reset and counter-increment to number items
  • Use ::before and content to display the counter
  • Create nested numbering like 1.1, 1.2 using two counters

Try a Solution:

.steps {
  counter-reset: step;
  list-style: none;
  padding: 0;
  margin: 0 0 18px;
  max-width: 520px;
}

.steps li {
  counter-increment: step;
  padding: 12px 12px 12px 52px;
  border: 1px solid #eee;
  border-radius: 12px;
  margin-bottom: 10px;
  position: relative;
}

.steps li::before {
  content: counter(step);
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 28px;
  height: 28px;
  line-height: 28px;
  text-align: center;
  border-radius: 999px;
  border: 1px solid #d6e4ff;
  background: #f3f6ff;
  font-weight: bold;
  font-size: 13px;
}

.outline {
  counter-reset: section;
  list-style: none;
  padding: 0;
  margin: 0;
}

.outline > li {
  counter-increment: section;
  margin-bottom: 10px;
}

.outline > li::before {
  content: counter(section) ". ";
  font-weight: bold;
}

.outline ul {
  counter-reset: sub;
  list-style: none;
  padding-left: 22px;
  margin: 8px 0 0;
}

.outline ul li {
  counter-increment: sub;
  margin-bottom: 6px;
}

.outline ul li::before {
  content: counter(section) "." counter(sub) " ";
  color: #555;
  font-weight: 600;
}

What’s Next?

Next, you will learn CSS units such as px, %, em, rem, vw, and vh.

CSS Counters Examples (9)