Ordered lists aren't the only elements that can be automatically numbered. Thanks to the various counter-related properties, any element can be.

body {
  counter-reset: my-awesome-counter;
section {
  counter-increment: my-awesome-counter;
section:before {
  content: counter(my-awesome-counter);

Each <section> will respectively start with "1", "2", "3", or "4".

You can control the style of the counter by comma separating the counter function. e.g. to make them use Roman numerals:

section:before {
  content: counter(my-awesome-counter, upper-roman);


On CodePen:

More Information

Browser Support

Chrome Safari Firefox Opera IE Android iOS
2+ 3.1+ Any 9.2+ 8+ TBD TBD


  1. User Avatar
    Chris Bier

    The guy drove home without paying for the skirt steak! haha

  2. User Avatar

    hmm it looks like Android and iOS has a good support too.

  3. User Avatar
    Permalink to comment#

    Event without script we can change number of li with counter-increament

    • User Avatar
      Permalink to comment#

      I have edited your code a bit so it is actually working.

      You have to move counter-increment property from li:before to li itself. Also in counter-reset property you cannot use commas, just spaces to separate values.

    • User Avatar
      Permalink to comment#

      @transGLUKator Thanks for the note.

      But can you explain why the article demo as the counter reset value seperated by commas ?

  4. User Avatar
    Permalink to comment#

    Is it possible to use it like this:

    div:nth-child(counter(item)) {

    I can’t get it working, would be nice if it would work that way also.

    • User Avatar

      I’m almost certain that ‘counter’ only works within the ‘content’ property on pseudo elements (e.g. ::before, ::after)

  5. User Avatar
    Permalink to comment#

    is there any technique or advice on how to make the counters clickable links? I can’t see how but I’ve been asked to do so on an already established design.

    • User Avatar

      Couldn’t you just wrap it up inside an anchor tag?

      <a class="counter-link"><a/>

      Then in your css, try something like..

      .counter-link {
          &::before {
              content: counter(NAME_OF_COUNTER);
  6. User Avatar

    I’ve run into an issue where I have code like so:

    #map { counter-reset: markerLabel; }
    #map .MarkerLabel {
        counter-increment: markerLabel;
        &::before {  content: ~"counter(markerLabel)";  }
        &:hover {  /* stuff */ }

    This works no problem on page load. The problem I’m running into is whenever I hover over .MarkerLabel, it seems to be inserting an additional ::before pseudo element inside the .MarkerLabel. So I end up with the original ::before pseudo element that has a counter value of 1 and then when I hover, a second pseudo element appears with a counter value (in this case) of 54, like it’s doing it all over again on hover. Make no sense to me. Anyone else run into issues with :hover and the CSS counter?

    • User Avatar

      It was an issue with the Google Maps API rendering two sets of markers. So I just limited the counter to the first set of .MarkerLabels.

  7. User Avatar
    Permalink to comment#

    Here is youtube video tutorial, i explained this in little detail with examples. :)

  8. User Avatar
    Aaron Davidson
    Permalink to comment#

    There’s a big undocumented aspect to using multiple CSS counters which this pen demonstrates
    That’s neither how I expected it to work, nor how I think it should work.

Leave a Comment

Posting Code!

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.