htmlcsscss-counter

Prevent zero in nested ordered list when using css counters


I am styling an HTML nested ordered list (numbered). I am trying to achieve same layout as MS Word has usually when you press Tab before the numbered list item. Ex:

1. Item at top
1.1.1.1. Item at middle
2. Item at bottom

For now I have the following CSS which sets 1.0.0.1 for the Item at middle. Is there any way to fix that with CSS and without changing the HTML?

ol { counter-reset: itemCounter; padding-left: 0 }
ol li { list-style: none; }
ol li:not(:has(ol)):before {
    content: counters(itemCounter, ".") ". ";
    counter-increment: itemCounter;
}
<ol>
   <li>Item at top</li>
   <li>
      <ol>
         <li>
            <ol>
               <li>
                  <ol>
                     <li>Item at middle</li>
                  </ol>
               </li>
            </ol>
         </li>
      </ol>
   </li>
   <li>Item at bottom</li>
</ol>


Solution

  • This seems to work as you need it to:

    ol { counter-reset: itemCounter; padding-left: 0 }
    ol li { list-style: none; }
    ol li:not(:has(ol)):before {
        content: counters(itemCounter, ".") ". ";
        counter-increment: itemCounter;
    }
    
    ol>li:has(ol) {
      counter-increment: itemCounter 0;
    }
    
    ol>li ol li:has(ol) {
      counter-increment: itemCounter 1;
    }
    <ol>
       <li>Item at top</li>
       <li>
          <ol>
             <li>
                <ol>
                   <li>
                      <ol>
                         <li>Item at middle</li>
                         <li>Item at middle</li>
                      </ol>
                   </li>
                </ol>
             </li>
             <!-- a few li for testing 👇 -->
             <li>
                <ol>
                   <li>
                      <ol>
                         <li>Item at middle</li>
                      </ol>
                   </li>
                   <li>
                      <ol>
                         <li>Item at middle</li>
                         <li>Item at middle</li>
                      </ol>
                   </li>
                </ol>
             </li>
          </ol>
       </li>
       <li>Item at bottom</li>
    </ol>