Search code examples
css-counter

CSS counters for headings nested in div


I ran into a CSS issue which I can't solve of my own.

It's easy: The CSS counters work with headings without div, but don't work with headings in a div.

Look at the following examples...

This works

h1 {
  counter-reset: h2;
}

h2 {
  counter-reset: h3;
}

h3 {
  counter-reset: h4;
}

h2::before {
    counter-increment: h2;
    content: counter(h2) ". ";
}

h3::before {
    counter-increment: h3;
    content: counter(h2) "." counter(h3) ". ";
}

h4::before {
    counter-increment: h4;
    content: counter(h2) "." counter(h3) "." counter(h4) ". ";
}
<h1>Title</h1>

<h2>Section 1</h2>

<h2>Section 2</h2>

<h3>Subsection 1</h3>

<h3>Subsection 2</h3>

<h4>Subsubsection 1</h4>

<h4>Subsubsection 2</h4>

<h2>Section 3</h2>

This doesn't work (counts work)

h1 {
  counter-reset: h2;
}

h2 {
  counter-reset: h3;
}

h3 {
  counter-reset: h4;
}

h2::before {
    counter-increment: h2;
    content: counter(h2) ". ";
}

h3::before {
    counter-increment: h3;
    content: counter(h2) "." counter(h3) ". ";
}

h4::before {
    counter-increment: h4;
    content: counter(h2) "." counter(h3) "." counter(h4) ". ";
}
<h1>Title</h1>

<div><h2>Section 1</h2></div> <!-- correct: 1. -->

<div><h2>Section 2</h2></div> <!-- correct: 2. -->

<div><h3>Subsection 1</h3></div> <!-- correct: 2.1. -->

<div><h3>Subsection 2</h3></div> <!-- wrong: 2.1. instead of 2.2 -->

<div><h4>Subsubsection 1</h4></div> <!-- wrong: 2.0.1 instead of 2.2.1 -->

<div><h4>Subsubsection 2</h4></div> <!-- wrong: 2.0.1 instead of 2.2.2 -->

<div><h2>Section 3</h2></div> <!-- correct: 3. -->

Maybe somebody knows a fix for this issue and can explain why this happens.

Help is highly appreciated.


Solution

  • If we give the divs a class name and switch the counter-reset to these classes it works.

    h1 {
      counter-reset: h2;
    }
    
    .h2 {
      counter-reset: h3;
    }
    
    .h3 {
      counter-reset: h4;
    }
    
    h2::before {
        counter-increment: h2;
        content: counter(h2) ". ";
    }
    
    h3::before {
        counter-increment: h3;
        content: counter(h2) "." counter(h3) ". ";
    }
    
    h4::before {
        counter-increment: h4;
        content: counter(h2) "." counter(h3) "." counter(h4) ". ";
    }
    <h1>Title</h1>
    
    <div class="h2"><h2>Section 1</h2></div>
    
    <div class="h2"><h2>Section 2</h2></div>
    
    <div class="h3"><h3>Subsection 1</h3></div>
    
    <div class="h3"><h3>Subsection 2</h3></div>
    
    <div class="h4"><h4>Subsubsection 1</h4></div>
    
    <div class="h4"><h4>Subsubsection 2</h4></div>
    
    <div class="h3"><h2>Section 3</h2></div>