How to Display an Ordered List with Nested Counters

Solutions with CSS

You can display an ordered list with nested counters like 1.1, 1.2 instead of 1, 2 by using CSS. In this snippet, you’ll find some methods of displaying such numbers.

Example of displaying an ordered list with nested counters with the “block” value of the display property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      ol {
        counter-reset: item;
      }
      li {
        display: block;
        color: #666666;
      }
      li:before {
        content: counters(item, ".") " ";
        counter-increment: item;
      }
    </style>
  </head>
  <body>
    <ol>
      <li>Element 1
        <ol>
          <li>Sub element 1</li>
          <li>Sub element 2</li>
          <li>Sub element 3</li>
        </ol>
      </li>
      <li>Element 2</li>
      <li>Element 3
        <ol>
          <li>Sub element 1</li>
          <li>Sub element 2</li>
          <li>Sub element 3</li>
        </ol>
      </li>
    </ol>
  </body>
</html>

Result

  1. Element 1
    1. Sub element 1
    2. Sub element 2
    3. Sub element 3
  2. Element 2
  3. Element 3
    1. Sub element 1
    2. Sub element 2
    3. Sub element 3

In the example above, we set the display property to “block” for the <li> element. We applied the :before pseudo-element and then, added the content and counter-increment properties. For the <ol> element, we specified the counter-reset property set to “item”.

Let’s see another example.

Example of displaying an ordered list with nested counters with the “table” value of the display property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      ol {
        list-style-type: none;
        counter-reset: item;
        margin: 0;
        padding: 0;
      }
      li {
        display: table;
        counter-increment: item;
        margin-bottom: 0.6em;
      }
      li:before {
        content: counters(item, ".") ". ";
        display: table-cell;
        padding-right: 0.6em;
      }
      li li {
        margin: 0;
      }
      li li:before {
        content: counters(item, ".") " ";
      }
    </style>
  </head>
  <body>
    <ol>
      <li>Element 1
        <ol>
          <li>Sub element 1</li>
          <li>Sub element 2</li>
          <li>Sub element 3</li>
        </ol>
      </li>
      <li>Element 2</li>
      <li>Element 3
        <ol>
          <li>Sub element 1</li>
          <li>Sub element 2</li>
          <li>Sub element 3</li>
        </ol>
      </li>
    </ol>
  </body>
</html>

Here, we set the display of the <li> element to “table” and used the “table-cell” value for the :before pseudo-element applied to the <li> element.