Questioner
Questioner

Reputation: 123

Counter keeps resetting in HTML/CSS

I am trying to write an electronic book, and I'm having problems with counters for managing chapters/sections/subsections.

body {
  counter-reset: chapter;
  counter-reset: section;
  counter-reset: subsection;
}

h1.chapter::before {
  counter-reset: section;
  counter-reset: subsection;
  counter-increment: chapter;
  content: "Chapter " counter(chapter) ": ";
}

h2.section::before {
  counter-reset: subsection;
  counter-increment: section;
  content: "Section " counter(chapter) "." counter(section) ": ";
}

h3.subsection::before {
  counter-increment: subsection;
  content: "Subsection " counter(chapter) "." counter(section) "." counter(subsection) ": ";
}
<h1 class="chapter"> The first chapter</h1>
<h2 class="section"> The first section </h2>
<h2 class="section"> The second section </h2>
<h3 class="subsection"> The first subsection </h3>
<h3 class="subsection"> The second subsection </h3>
<h1 class="chapter"> The second chapter</h1>
<h2 class="section"> The second chapter's first section</h2>
<h3 class="subsection"> The second chapter's first subsection </h3>

and this is what shows up:

enter image description here

So I have no idea why the chapter and section just don't stick while `subsection' doesn't reset...

Upvotes: 1

Views: 1369

Answers (2)

Temani Afif
Temani Afif

Reputation: 272589

You have to use only one reset per element or you will simply override the first ones with the last one like with any properties.

enter image description here

You should also pay attention to where you need to use counter-reset:

Counters are "self-nesting", in the sense that resetting a counter in a descendant element or pseudo-element automatically creates a new instance of the counter.

Then

The scope of a counter starts at the first element in the document that has a 'counter-reset' for that counter and includes the element's descendants and its following siblings with their descendants ref

Considering this you shouldn't reset the counter inside a pseudo-element but the element itself so that the sibling elements will have the good value.

body {
  counter-reset: chapter section subsection;
}
h1.chapter {
  counter-reset: section subsection;
}
h1.chapter::before {
  counter-increment: chapter;
  content: "Chapter " counter(chapter) ": ";
}

h2.section {
  counter-reset: subsection;
}
h2.section::before {
  counter-increment: section;
  content: "Section " counter(chapter) "." counter(section) ": ";
}

h3.subsection::before {
  counter-increment: subsection;
  content: "Subsection " counter(chapter) "." counter(section) "." counter(subsection) ": ";
}
<h1 class="chapter"> The first chapter</h1>
<h2 class="section"> The first section </h2>
<h2 class="section"> The second section </h2>
<h3 class="subsection"> The first subsection </h3>
<h3 class="subsection"> The second subsection </h3>
<h1 class="chapter"> The second chapter</h1>
<h2 class="section"> The second chapter's first section</h2>
<h3 class="subsection"> The second chapter's first subsection </h3>

You can also simplify your code like below:

body {
  counter-reset: chapter; /*we reset the chapter once*/
}
h1.chapter {
  counter-reset: section; /*we reset the section each chapter*/
}
h1.chapter::before {
  counter-increment: chapter;
  content: "Chapter " counter(chapter) ": ";
}

h2.section {
  counter-reset: subsection; /*we reset the subsection each section*/
}
h2.section::before {
  counter-increment: section;
  content: "Section " counter(chapter) "." counter(section) ": ";
}

h3.subsection::before {
  counter-increment: subsection;
  content: "Subsection " counter(chapter) "." counter(section) "." counter(subsection) ": ";
}
<h1 class="chapter"> The first chapter</h1>
<h2 class="section"> The first section </h2>
<h2 class="section"> The second section </h2>
<h3 class="subsection"> The first subsection </h3>
<h3 class="subsection"> The second subsection </h3>
<h1 class="chapter"> The second chapter</h1>
<h2 class="section"> The second chapter's first section</h2>
<h3 class="subsection"> The second chapter's first subsection </h3>

Upvotes: 2

disinfor
disinfor

Reputation: 11532

You need to move the reset from the pseudo element. Also, you can reformat the counter-reset on the body to include all of them in one statement.

body {
  counter-reset: chapter section subsection;
}

h1.chapter::before {
  counter-increment: chapter;
  content: "Chapter " counter(chapter) ": ";
}

h1.chapter {
  counter-reset: section;
}

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

h2.section {
  counter-reset: subsection;
}

h3.subsection::before {
  counter-increment: subsection;
  content: "Subsection " counter(chapter) "." counter(section) "." counter(subsection) ": ";
}
<h1 class="chapter"> The first chapter</h1>
<h2 class="section"> The first section </h2>
<h2 class="section"> The second section </h2>
<h3 class="subsection"> The first subsection </h3>
<h3 class="subsection"> The second subsection </h3>
<h1 class="chapter"> The second chapter</h1>
<h2 class="section"> The second chapter's first section</h2>
<h3 class="subsection"> The second chapter's first subsection </h3>

Here is a fiddle to play with: https://jsfiddle.net/muc0q9aw/

Upvotes: 3

Related Questions