5

How to increment ordered list with numbers and alphabet letters in CSS:

    ol.nested { 
        margin-bottom: 0;
        counter-reset: item;
    }
    
    ol.nested li { 
        display: block;
        position: relative;
    }
    
    ol.nested li:before { 
        content: counters(item, ".", decimal) "."; 
        counter-increment: item;
        position: absolute;
        margin-right:100%;
        right: 10px;
    }
<ol class="nested">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3
    <ol class="nested">
        <li>Show Item 3.a instead of 3.1</li>
        <li>Show Item 3.b instead of 3.2</li>
        <li>Show Item 3.c instead of 3.3</li>
    </ol>
    </li>
    <li>Item 4
 <ol class="nested">
        <li>Show Item 4.a instead of 4.1</li>
        <li>Show Item 4.b instead of 4.2</li>
        <li>Show Item 4.c instead of 4.3</li>
    </ol>
 </li>
 <li>Item 5</li>
</ol>

Is there a way to combine numbers with letters (2.a, 2.b, 2.c) and increment them in ordered list? With content and counters-increment the list will be incremented only with one type either decimal or lower-alpha. How to combine decimal with lower-alpha incrementing? Thank you!

dippas
  • 58,591
  • 15
  • 114
  • 126
zimny
  • 136
  • 1
  • 8

2 Answers2

6

you can use multiple counters with multiple counter-reset, and apply a counter-increment to ::before and ::after

.nested {
  margin-bottom: 0;
  counter-reset: number letter; /* default reset for number and letter */
}

.nested.third li {
  counter-reset: number 2; /* reset all child li in order to keep 3.x */
}

.nested.fourth {
  counter-reset: letter  /* reset the letter to restart at A */
}

.nested.fourth li {
  counter-reset: number 3;  /* reset all child li in order to keep 4.x */
}

.nested li {
  display: block;
  position: relative;
}

.parent li::before {
  content: counter(number)".";
  counter-increment: number; /* increment the numbers in general */
  position: absolute;
  margin-right: 100%;
  right: 20px;
  background: lightgreen
}

.child li::after {
  content: counter(letter, lower-alpha); /* increment the letters in general */
  counter-increment: letter;
  position: absolute;
  margin-right: 100%;
  right: 10px;
  background: lightblue;
  width: 10px
}
<ol class="nested parent">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3
    <ol class="nested child third">
      <li>Show Item 3.a instead of 3.1</li>
      <li>Show Item 3.b instead of 3.2</li>
      <li>Show Item 3.c instead of 3.3</li>
    </ol>
  </li>
  <li>Item 4
    <ol class="nested child fourth">
      <li>Show Item 4.a instead of 4.1</li>
      <li>Show Item 4.b instead of 4.2</li>
      <li>Show Item 4.c instead of 4.3</li>
    </ol>
  </li>
  <li>Item 5</li>
</ol>

OP's comment

Sorry, you're right. The numbers are exactly as I asked. Is there no way to have generic css class for the next items 5, 6, 7 and so on? Hm.

As @Mr Lister answered below you can do it, so I'm updating my answer to meet your specs.

As you can see by the colors, the difference from one snippet to another is that in the first one you have more control over each item, in this one is more general.

.nested li {
  display: block;
  position: relative;
}


.nested {
  margin-bottom: 0;
  counter-reset: number;
}


.parent .nested {
  counter-reset: letter;
}

.parent .nested li::before {
  content: counter(number) "." counter(letter, lower-alpha);
  counter-increment: letter;
  background: lightblue
}


.nested li::before {
  content: counter(number) ".";
  counter-increment: number;
  position: absolute;
  margin-right: 100%;
  right: 10px;
  background: lightgreen
}
<ol class="nested parent">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3
    <ol class="nested">
      <li>Show Item 3.a instead of 3.1</li>
      <li>Show Item 3.b instead of 3.2</li>
      <li>Show Item 3.c instead of 3.3</li>
    </ol>
  </li>
  <li>Item 4
    <ol class="nested">
      <li>Show Item 4.a instead of 4.1</li>
      <li>Show Item 4.b instead of 4.2</li>
      <li>Show Item 4.c instead of 4.3</li>
    </ol>
  </li>
  <li>Item 5</li>
</ol>
dippas
  • 58,591
  • 15
  • 114
  • 126
  • Is not exactly what I need. Instead of "3.b" the number is "4.b". How to make .third and .fourth class generic for all next numbers, e.g. (5.a; 5.b; 5.c) without to write the next css class? – zimny Nov 21 '17 at 11:56
  • what?? it is EXACTLY how you asked, the "3.b" is indeed 3.b" and so on. you can't have generic classes for this specif question [**SCREENSHOT**](https://i.imgur.com/YLpA9nK.png) – dippas Nov 21 '17 at 11:59
  • Sorry, you're right. The numbers are exactly as I asked. Is there no way to have generic css class for the next items 5, 6, 7 and so on? Hm... – zimny Nov 21 '17 at 12:23
4

Is this what you need? It doesn't rely on any specific class names for the different nested lists, so you can have as many lists as you want.
The trick is to use items for the outer list and subitems for the inner ones.

ol.nested {
  margin-bottom: 0;
  counter-reset: item;
}

ol.nested li {
  display: block;
  position: relative;
}

ol.nested li:before {
  content: counters(item, ".", decimal) ".";
  counter-increment: item;
  position: absolute;
  margin-right: 100%;
  right: 10px;
}

.nested .nested {
  counter-reset: subitem;
}

.nested .nested li:before {
  content: counter(item) "." counter(subitem, lower-alpha);
  counter-increment: subitem;
}
<ol class="nested">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3
    <ol class="nested">
      <li>Show Item 3.a instead of 3.1</li>
      <li>Show Item 3.b instead of 3.2</li>
      <li>Show Item 3.c instead of 3.3</li>
    </ol>
  </li>
  <li>Item 4
    <ol class="nested">
      <li>Show Item 4.a instead of 4.1</li>
      <li>Show Item 4.b instead of 4.2</li>
      <li>Show Item 4.c instead of 4.3</li>
    </ol>
  </li>
  <li>Item 5</li>
</ol>
Mr Lister
  • 45,515
  • 15
  • 108
  • 150