Search code examples
csshtml-lists

"Halt" ordered list numbering


I got inspired by this answer on another topic and tried to utilize it in my own situation in order to get rid of having to manually insert some start=x in some ol's in a page, but my situation is far more complex than that one, so I can't make it work exactly how I want...

So I have some ol's, each one following an h3 tag. Now, the hard part is that there may be some li's that shouldn't get an ordering, and on top of that, there may exist some ol's with just one li inside, where that single li shouldn't get an ordering either...

So it's like:

<h3>Some title</h3>
<ol>
    <li>One item</li>
    <li class="no-style">Second item that shouldn't get ordered and shouldn't increment the next item either</li>
    <li>Third item, ordered with number 2</li>
</ol>
<h3>Some other title</h3>
<ol>
    <li>Another list's first item</li>
    <li>Another list's second item</li>
    <li>Another list's third item</li>
</ol>
<h3>And yet another title</h3>
<ol>
   <li>A single item here that shouldn't get ordered</li>
</ol>

So the above code should produce the following result:

Some title
  1. One item
     Second item that shouldn't get ordered and shouldn't increment the next item either
  2. Third item, ordered with number 2
Some other title
  1. Another list's first item
  2. Another list's second item
  3. Another list's third item
And yet another title
     A single item here that shouldn't get ordered

So I experimented with many variations of the following CSS, but nothing worked the way it should:

li:only-of-type, li.no-style { list-style-type: none; }
h3 + ol { counter-reset: mycounter; }
h3 + ol > li:not(.no-style) + li:before, h3 + ol > li:first-of-type:not(.no-style):before { counter-increment: mycounter; } 
h3 + ol > li:not(.no-style):before { content: counter(mycounter) ". "; }

Basically, the idea is to counter-increment mycounter only when the previous li doesn't have the class no-style, and also, make the whole numbering disappear when the li is the only-of-type...

I hope, as soon as I catch some sleep since it's too late in my timezone and I'm exhausted, that I'll be able to get this to work, unless someone expert in CSS gets to find the correct syntax first, and can help me a little bit.

Thanks in advance for any possible help that I receive.


Solution

  • If I understood you correctly, then perhaps these examples below can help you somehow. You can combine both solutions completely for your needs.

    Example #1. By default, lists have display: list-item; To simply disable the intermediate element, it is enough to assign it display: block; (or any other), as can be seen in the example:

    h3 + ol > li:only-child,
    .no-style {
      display: block;
    }
    <h3>Some title</h3>
    <ol>
      <li>One item</li>
      <li class="no-style">Second item that shouldn't get ordered and shouldn't increment the next item either</li>
      <li>Third item, ordered with number 2</li>
    </ol>
    <h3>Some other title</h3>
    <ol>
      <li>Another list's first item</li>
      <li>Another list's second item</li>
      <li>Another list's third item</li>
    </ol>
    <h3>And yet another title</h3>
    <ol>
      <li>A single item here that shouldn't get ordered</li>
    </ol>

    Example #2. If you need full control over the counters, then you will have to use properties such as (counter-increment, counter-reset, etc.). Example below:

    li:only-of-type,
    li.no-style {
      list-style-type: none;
    }
    
    h3 + ol {
      list-style: none;
      counter-reset: mycounter;
    }
    
    h3 + ol > li:before {
      counter-increment: mycounter;
      content: counter(mycounter) ". ";
    }
    
    h3 + ol > li:only-child:before,
    .no-style:before {
      counter-increment: none !important;
      content: "0. " !important; /* hold the indent */
      list-style-type: none;
      visibility: hidden;
    }
    <h3>Some title</h3>
    <ol>
      <li>One item</li>
      <li class="no-style">Second item that shouldn't get ordered and shouldn't increment the next item either</li>
      <li>Third item, ordered with number 2</li>
    </ol>
    <h3>Some other title</h3>
    <ol>
      <li>Another list's first item</li>
      <li>Another list's second item</li>
      <li>Another list's third item</li>
    </ol>
    <h3>And yet another title</h3>
    <ol>
      <li>A single item here that shouldn't get ordered</li>
    </ol>

    To cancel the increment in a specific selector, it is enough to use counter-increment: none;.

    For elements that are the only ones in their parent, you can use the pseudo-class :only-child.