Determine the number of elements in a Css selector and restart the counter whenever an element

Need help with counting elements that are not part of a regular list structure.

Here is a code example to clarify: Fiddle

I don't have much control over the HTML.


The DOM structure looks like this:

 <div class="body">
  <div><p class="numlist" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>
  <!-- Only here for only here in demonstrative purpose -->
  <div class="should-reset"><p>Start a new counter for the inlines</p></div>
  <div><p class="numlist depth">first text</p></div>
  <div><p class="numlist depth">second text</p></div>
  <div><p class="numlist depth">third text</p></div>
  <!-- Only here for only here in demonstrative purpose -->
  <div class="should-reset"><p>Want to reset the standard counter</p></div>
  <div><p class="numlist reset" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>      
</div>

I am aiming for a result like this:

1. list one
2. list one
3. list one
     1. list two
     2. list two
     3. list two
1. list three
2. list three
3. list three    

However, list three does not reset as desired and ends up like this:

1. list three
4. list three
5. list three    

Answer №1

Why not consider using <ol> elements for this purpose?

Note: The request to avoid certain HTML elements was only communicated after I provided my initial answer: "I have limited control over the html."

.inset {
  margin-left: 20px;
}
<ol>
  <li>
    first text
  </li>
  <li>
    second text
  </li>
  <li>
    third text
  </li>
  </ol>

  <ol class="inset">
    <li>
      first text
    </li>
    <li>
      second text
    </li>
    <li>
      third text
    </li>
  </ol>
  
  <ol>
    <li>
      first text
    </li>
    <li>
      second text
    </li>
    <li>
      third text
    </li>
  </ol>

Answer №2

.body {
  counter-reset: standard;  
}

.should-reset {
  counter-reset: standard;
  color: red;
}

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

.numlist.depth::before {
  margin-left: 50px;
}
<div class="body">
  <div><p class="numlist" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>
  <div class="should-reset"><p>Start a new counter for the inlines</p> </div>
  <div><p class="numlist depth" depth>first text</p></div>
  <div><p class="numlist depth" depth>second text</p></div>
  <div><p class="numlist depth" depth>third text</p></div>
  <div class="should-reset"><p>Want to reset the standard counter</p> </div>
  <div><p class="numlist" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>
</div>

UPDATE:

.custom-body {
  counter-reset: standard;  
}

.custom-body div:nth-child(3n + 1) {
  counter-reset: standard;
}

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

.numlist.depth::before {
  margin-left: 50px;
}
<div class="custom-body">
  <div><p class="numlist reset" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>
  <div><p class="numlist depth" depth>first text</p></div>
  <div><p class="numlist depth" depth>second text</p></div>
  <div><p class="numlist depth" depth>third text</p></div>
  <div><p class="numlist" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>
</div>

Answer №3

The counter-reset you have used at

<div><p class="numlist reset" >first text</p></div>
does not reset the original counter as expected. Instead of resetting the existing counter, a new counter with the same name is created within the scope of the P element and any subsequent siblings or children.

To illustrate this, consider replacing counter(standard) with "counters(standard," AND "):

.body {
  counter-reset: standard inline;  
}

div > p.numlist::before {
  counter-increment: standard;
  content: counters(standard," AND ") ". ";
}

div > p.numlist.depth::before {
  counter-increment: inline;
  content: counter(inline) ". ";
  margin-left: 50px;
}

.should-reset {
  color: red;
}

div > p.numlist.reset {
  counter-reset: standard;
}
<div class="body">
  <div>
    <p class="numlist" >first text</p>
  </div>
  <div>
    <p class="numlist">second text</p>
  </div>
  <div>
    <p class="numlist">third text</p>
  </div>
<!-- Only here for only here in demonstrative purpose -->
  <div class="should-reset">
    <p>
      Start a new counter for the inlines
    </p> 
  </div>
  <div>
    <p class="numlist depth" depth>first text</p>
  </div>
  <div>
    <p class="numlist depth" depth>second text</p>
  </div>
  <div>
    <p class="numlist depth" depth>third text</p>
  </div>
  <!-- Only here for only here in demonstrative purpose -->
    <div class="should-reset">
    <p>
    Want to reset the standard counter
    </p> 
  </div>
  <div>
    <p class="numlist reset" >first text</p>
  </div>
  <div>
    <p class="numlist">second text</p>
  </div>
  <div>
    <p class="numlist">third text</p>
  </div>
  
</div>

In this scenario, the counters() function displays all instances of counters with the given name visible within the current scope, rather than just the most locally defined one. However, a counter-reset cannot reset instances from higher scopes.

This behavior is not a browser bug but is actually well-documented by W3C CSS Working Group. According to https://drafts.csswg.org/css-lists-3/#nested-counters:

Counters are “self-nesting”; instantiating a new counter on an element which inherited an identically-named counter from its parent creates a new counter of the same name, nested inside the existing counter. This is important for situations like lists in HTML, where lists can be nested inside lists to arbitrary depth: it would be impossible to define uniquely named counters for each level. The counter() function only retrieves the innermost counter of a given name on the element, whereas the counters() function uses all counters of a given name that contain the element.

The scope of a counter therefore starts at the first element in the document that instantiates that counter and includes the element’s descendants and its following siblings with their descendants. However, it does not include any elements in the scope of a counter with the same name created by a counter-reset on a later sibling of the element, allowing such explicit counter instantiations to obscure those earlier siblings.

If modifying the HTML directly is not an option, and the <div class="should-reset"> tags are purely informational, achieving this solely through CSS is challenging. A pseudo-class like :has() would be required, such as:

div:has(> p.numlist.reset) {
  counter-reset: standard;
}

However, as of now, the :has() pseudo-class is not supported in major browsers due to performance concerns. Even if implemented, it would create a nested counter instead of resetting the original counter.

In conclusion, the issue you are facing with counter-reset is not a bug in browsers but a part of the specified behavior documented by the W3C CSS Working Group.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Checkbox and Ionic avatar image combined in a single line

I am currently working on a mobile app using the ionic framework. I would like to create a layout with an avatar image on the left, text in the middle, and a checkbox on the right. Can anyone provide guidance on how to achieve this? The code snippet below ...

Loop through the <li> elements and use jQuery to update the text

Check out this HTML setup: <div class="mydiv"> <ul> <li>Text 1</li> <li>Text 2</li> </ul> <ul> <li>Text 3</li> <li>Text 4</li> </ul> <ul> < ...

As you scroll, a box blocks off half of the screen

Hey everyone, I could really use your assistance! I'm working on developing a javascript code and here is the idea - if anyone can contribute to it. It's like a social media platform where users enter the site and the is_user_logged_in parameter ...

Efficiently passing parameters to AJAX URLs in Django

When trying to pass a parameter to the URL path to specify which user's role I want to change, I keep encountering an error. NoReverseMatch at /manageuser/ Reverse for 'editrole' with keyword arguments '{'user_name': &apo ...

How can I include a close/ok button at the bottom of a bootstrap multiselect component?

Currently, I am utilizing the Bootstrap multiselect tool to filter query outcomes on a specific page. After selecting one or multiple options, my goal is to have a "close" or "OK" button visible at the bottom of the selection list. Upon clicking this butto ...

(CSS) Unusual phantom white outline surrounding menu with no visible border

I've just finished creating my first multi-level drop-down menu, but I'm encountering two white border issues. The first white border appears at the bottom of the menu and seems to be related to the padding of the a-elements. The specific area in ...

The "html" element fails to achieve a full height when applying a 100% height setting

I am facing a height problem of 100% <!doctype html> <html> <head> <meta charset="utf-8"> <title>My Dreamweaver Website</title> <link rel="stylesheet" href="style.css"> </head> <body> <section clas ...

Issues with PHP Mail Forms not functioning as intended

I've been struggling for hours trying to figure this out. I'm new to PHP mail form coding and any assistance would be greatly appreciated! Below are two images: one of the HTML code and one of the PHP code. It seems like a simple setup, but even ...

Is it necessary to mark all checkboxes in the initial column of the gridview?

I have encountered an issue with my code that checks all checkboxes in the first column of a gridview. It seems to work only for Internet Explorer versions 5.0 to 8.0, but gives a Javascript error when running on IE 9 and above stating "Function Expected ...

The alignment issue persists in HTML/CSS despite troubleshooting efforts

I am facing a challenge while attempting to center text within a modal window, despite my efforts the text remains uncentered. This is my HTML code: <div ng-init="modalCompassDir()"> <div class="myModal"> <img class='floor ...

Switch between different classes with JavaScript

Here is the code that I am working with: This is the HTML code: <div class="normal"> <p>This is Paragraph 1</p> <p>This is Paragraph 2</p> <p>This is Paragraph 3</p> <p>This is Paragraph 4&l ...

Ways to adjust the div height to match the span height

.headerDesc { width: 100% + 1px; height: 70px; background-color: #4d2765; margin: 0 -8px; } .headerDesc span { padding: 5px; position: absolute; color: white; font-family: 'Arial', sans-serif; text-al ...

Generate a new perspective by incorporating two distinct arrays

I have two arrays containing class information. The first array includes classId and className: classes = [ {classid : 1 , classname:"class1"},{classid : 2 , classname:"class2"},{classid : 3 , classname:"class3"}] The secon ...

Steps to bring life to your JavaScript counter animation

I need to slow down the counting of values in JavaScript from 0 to 100, so that it takes 3 seconds instead of happening instantly. Can anyone help me with this? <span><span id="counter"> </span> of 100 files</span> <s ...

Style your content using PHP and CSS to format text with multiple selectors

My HTML code looks like this: <div id="main"> <aside class="readableCenterAside left"> ## Content 1 ## </aside> <aside class="readableCenterAside right"> ## Content 2 ## </aside> </div> Here is my CSS: .readableCe ...

Effects of jQuery Show / Hide on adjacent select box operations

I created a pair of select boxes where the visibility of one is controlled by the other. Initially, the controlled select box (#select02) works perfectly on page load as long as I don't show/hide it by selecting options in the controlling select box ( ...

What could be the reason for the CSS file not getting applied to the HTML in my project?

Having trouble applying an external CSS file to my HTML file. Currently working on a Cloud IDE (goormIDE, similar to C9) and trying to link an external CSS file to my HTML file on the web server using Node.js. However, the CSS file is not being applied to ...

I need the links to open up the content area on the website in HTML

Is it possible to have a fixed header that does not disappear when clicking links from the navigation bar? I tried dividing the page into tables to achieve this. Now, I want to open the links in the navigation bar in the right column (the main content col ...

Enter the variable into the parameter

I'm working with some Javascript code: document.getElementById("Grid").style.gridTemplateRows = "repeat(3, 2fr)"; I'm trying to insert a variable as an argument to modify my CSS style. When I attempt the following: "repe ...

Pause jQuery at the conclusion and head back to the beginning

As a beginner in the world of jQuery, I am eager to create a slider for my website. My goal is to design a slideshow that can loop infinitely with simplicity. Should I manually count the number of <li> elements or images, calculate their width, and ...