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

Troubleshooting Hierarchical Ordering in Django-MPTT's recursetree Function

I am currently utilizing the django-mptt package within my Django application, and I have encountered an issue when trying to use the .order_by() method in conjunction with a filter. Despite attempting different criteria for ordering, the results remain un ...

Managing the width of an HTML table column based on its text content dynamically

Here is an example of an html table : <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td width="480px" class="societe" ><div style="float:left;font-size:12px;padding-top:2px" ><?php echo $_SESSION ...

How can you utilize the Array submission syntax within HTML coding?

I currently have numerous input fields within a form, and some of them are structured like this: <input name="agents[]" type="file" /> Additionally, imagine there is a plus button next to this field as shown below: <img src="plus.jpg" id="some_ ...

Looping through a nested for loop within an HTML table

I am currently working on generating a dynamic table using Lists of varying sizes. My first list is a List of Cars List<Car>. I have successfully placed the names of different car companies in the header. Next, I have a List<List<CarSales>& ...

Creating a diverse layout by dynamically adding divs without achieving uniformity in the grid

I'm working on dynamically generating a grid of divs with a specific size using the code below: function createGrid(gridSize) { var container = document.getElementById('container'); for (var i = 0; i < gridSize; i++) { va ...

Having trouble setting a background image for my CSS button

Recently started experimenting with button styles and I wanted to create a design where there is a background image on the left of the button with text located on the right side of the image. Here's the code snippet I've been working on. Here&apo ...

After utilizing the function, the forward and back arrows are no longer visible

After setting up my slideshow, I encountered an issue where clicking the next or previous buttons caused them to shrink down and turn into small grey boxes. Has anyone experienced this before? This relates to PHP/HTML if ($_SERVER['REQUEST_METHOD&ap ...

CSS First Element

"When an element with a specific id has a first-child descendant that is any of the heading tags (h1, h2, h3, h4, h5, or h6), apply the following CSS styles:" I have come up with the following selector: #content:first-child h1, #content:first-child h2, ...

"Encountered a 404 Error while attempting an Ajax

I am relatively new to web development and I am currently working on making a post method function properly. Below is the ajax call that I have implemented: $.ajax({ type: "POST", url: '/Controllers/AddPropertyData', ...

What steps can be taken to prompt the layout to transition?

I have an element that sticks to the top based on the current scroll offset. The issue is that the layout doesn't update when there is space available after the stuck element. This creates a ghost gap where the stuck element used to be... http://fidd ...

overlapping text placed directly above another text

Is there a way to place a text fragment above another part of the same line? <div>Th<div class="ac">Am</div>is is an ex<div class="ac">E</div>ample line</div> If implemented, it should display as: Am E This ...

How to use jQuery to dynamically set the value of a column span in a

Struggling with setting the value for a table column span. Here is my jQuery code: $('tr td data-th=Name span').val('My span content...'); This is how my HTML appears: <tr> <td data-th="Name"><span class="edit-inpu ...

Need help fixing my issue with the try-catch functionality in my calculator program

Can someone assist me with my Vue.js calculator issue? I am facing a problem where the output gets added to the expression after using try and catch. How can I ensure that both ERR and the output are displayed in the {{output}} section? Any help would be a ...

What is the best way to achieve a stylish Bootstrap modal design with a blurred and transparent header, as well as a left sidebar that seamlessly blends into

Is it feasible to create a modal with a blurred (transparent) background for the header section, allowing the site to show through? Additionally, can a sidebar on the left side of the modal also be transparent and blurred, revealing the site underneath? C ...

Issue with displaying data using a custom pure pipe and boolean in ngIf condition

For my current web project, I require a friendship/follow feature. There are two roles involved: admins and regular users. Regular users have the ability to follow other users, while admins do not possess this capability. When a user wishes to follow anot ...

Guide to Setting the Color of a Link Using CSS

I’ve been attempting to change the color of an ALink using CSS, but it seems like I just can’t get it right. It’s clear that I’m missing something, as I’ve spent quite a bit of time tinkering with this seemingly simple issue and still can’t fi ...

Adding images to .xsl using XML

I have created a unique "blog" using XML and XLST. The format of the blog is as follows: <post id="1" category="Miscellaneous"> <ptitle>MiG-21</ptitle> <psubtitle>Mikoyan-Gurevich MiG-21</psubtitle> <image></image& ...

Implementing a PHP form for seamless image uploads

I have been attempting to upload a form that includes an image. I have successfully retrieved the data for the brand name and other fields. However, I am encountering an issue with retrieving the image name and type. Can someone please assist me in ident ...

Display flash messages consistently in a designated area on the webpage instead of appearing at the top of the page in Flask

{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} <div class="alert alert-{{ category }}" style=" ...

Managing multiple carousels simultaneously using the middle mouse button in Swiper.js

I am currently utilizing 5 carousels on my screen, all of which are operated by the same navigation buttons. In addition to this, I require the ability to control them using the middle mouse scroll. However, when I activate the mouse wheel control, only ...