When consecutive DOM elements are hidden, a message saying "Hiding N elements" will be displayed

Provided a set of elements (number unknown) where some elements should remain hidden:

<div id="root">
  <div>              1</div>
  <div class="hide"> 2</div>
  <div class="hide"> 3</div>
  <div class="hide"> 4</div>
  <div>              5</div>
  <div>              6</div>
  <div class="hide"> 7</div>
  <div>              8</div>
  <div class="hide"> 9</div>
  <div class="hide"> 10</div>
</div> 

Hiding the elements with the hide class using CSS is straightforward (.hide { display: none; }). However, the objective is to replace each consecutive section of hidden elements with a replacement element, such as

<div>Some elements were hidden</div>
, or more precisely
<div>N elements hidden</div>
where N represents the number of hidden elements within that specific range (3, 1, and 2 in the provided example). Consequently, the final result would appear as follows:

1, 3 Elements hidden, 5, 6, 1 Element hidden, 8, 2 Elements hidden

Firstly, can this be accomplished exclusively through CSS? Although I cannot conceive of a direct method, there may be inventive individuals proficient in selector usage who could provide a solution :)

If resolved with only CSS is unattainable, does an alternative path exist by adding JavaScript classes + utilizing ::before/::after pseudo-elements? In other words, without modifying any actual DOM elements?

Answer №1

If I were to tackle this issue, my preference would be to utilize Javascript. However, if you are determined to rely solely on CSS, there are a few clever tricks that can help you achieve the desired outcome:

.hide {
 counter-increment: hiddenElements;
 visibility: hidden;
 font-size: 0px; 
}

The use of

counter-increment: hiddenElements;
will automatically increment the value for each hidden element. The caveat is that this method does not function with display: none;. Therefore, I have resorted to employing visibility: hidden; and font-size: 0px; as alternative workarounds to produce a similar effect.

.hide + div:not(.hide):before {
  content: counter(hiddenElements) " element(s) hidden \A";
  white-space: pre;
}

This snippet outputs the number of hidden elements once it encounters a sequence of a hidden element followed by a visible one. It's crucial to have a final (potentially empty) <div></div> in place to ensure this triggers correctly.

.hide + div:not(.hide) + div {
  counter-reset: hiddenElements;
}

Following the display of the total hidden elements count, this code effectively resets the counter on the subsequent div.

A demonstration can be viewed below.

.hide {
 counter-increment: hiddenElements;
 visibility: hidden;
 font-size: 0px; 
}

.hide + div:not(.hide):before {
  content: counter(hiddenElements) " element(s) hidden \A";
  white-space: pre;
}

.hide + div:not(.hide) + div {
  counter-reset: hiddenElements;
}
<div id="root">
  <div>              1</div>
  <div class="hide"> 2</div>
  <div class="hide"> 3</div>
  <div class="hide"> 4</div>
  <div>              5</div>
  <div>              6</div>
  <div class="hide"> 7</div>
  <div>              8</div>
  <div class="hide"> 9</div>
  <div class="hide"> 10</div>
  <div></div>
</div>

While this approach indeed functions, it does come with some minor limitations. In my opinion, pursuing a JavaScript solution would be more advantageous. Feel free to post a question with the JavaScript tag, and I will gladly offer my support there as well.

Answer №2

While the question was not originally tagged with jQuery, I wanted to offer a solution that utilizes it:

$('#container div').each(function() {
  if ($(this).hasClass('hide')) {
    var count = $(this).nextUntil(':not(.hide)').addBack().length;
    $(this).html( count + ' elements hidden')
    $(this).next('.hide').hide()
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id="container">
  <div> 1</div>
  <div class="hide"> 2</div>
  <div class="hide"> 3</div>
  <div class="hide"> 4</div>
  <div> 5</div>
  <div> 6</div>
  <div class="hide"> 7</div>
  <div> 8</div>
  <div class="hide"> 9</div>
  <div class="hide"> 10</div>
</div>

Answer №3

Have you considered utilizing the css counter technique?
Explore more about using CSS counters here

#root {
  counter-reset: section;
}

#root > div.hide {
  counter-increment: section;
  width: 0;
  height: 0;
  overflow: hidden;
}

#root > .hide + div:not(.hide):before {
  color: red;
  display: block;
  height: 100%;
  width: 100%;
  content: counter(section) " element hidden";
}

#root > .hide + div:not(.hide) + div {
  counter-reset: section;
}

Check out this live example on JSFiddle


Oops, my bad for misinterpreting the question..
Leaving my previous answer here for reference.


How do you feel about this little hack?

.hide {
  transform: scale(0.0001);
  line-height: 80%;
}

.hide:before {
  content: 'This is hidden';
  transform: scale(10000);
  width: 100%;
  height: 100%;
  display: block;
}

Demo available at: Take a look at this demo link

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

The Vue v-for directive encountered an unrecognized property during rendering

Trying to grasp the concept of v-for in Vue JS, especially since I am a newcomer to this framework. Since I am utilizing Django, custom delimiters are necessary. I have a script example that appends a list of objects to a data property: var app = new Vue( ...

Can someone explain the inner workings of the Typescript property decorator?

I was recently exploring Typescript property decorators, and I encountered some unexpected behavior in the following code: function dec(hasRole: boolean) { return function (target: any, propertyName: string) { let val = target[propertyName]; ...

Is it possible to simultaneously center and display an iframe inline?

I have a YouTube video that I'm trying to center within a div. After adding display: block; to the CSS following advice from How to center an iframe horizontally?, it centers correctly, but now I want to display two images inline next to the iframe ...

Error: an empty value cannot be treated as an object in this context when evaluating the "businesses" property

An error is occurring stating: "TypeError: null is not an object (evaluating 'son['businesses']')". The issue arose when I added ['businesses'][1]['name'] to 'son' variable. Initially, there was no error wi ...

Real-time Property Availability Widget

I need assistance with creating a website for a homeowner who wants to rent out their property. The client requires a feature that allows them to log in and easily mark individual days as available or unavailable for rental by choosing specific colors for ...

Unexpected JSON response from jQuery AJAX call

Trying to make a request for a json file using AJAX (jQuery) from NBA.com Initially tried obtaining the json file but encountered a CORS error, so attempted using jsonp instead Resulted in receiving an object filled with functions and methods rather than ...

ReactJS encountering issue with sending POST request, blocked by CORS preflight options

Every time I try to send a POST request to the server, it always responds with an unexpected OPTIONS. My login application built with React and Apollo is experiencing issues. Upon form submission, a mutation should be sent to the server via a POST request ...

Obtaining variable content from a JavaScript function

Learning JS with documentation has been a challenging journey for me. The concept of variables inside and outside a function still confuses me. I'm interested in creating a module that allows me to reuse code written in different parts of my program ...

Looking to optimize the JavaScript code for improved performance speed

Is there a more efficient way to avoid writing the same lines of code repeatedly without compromising performance? I've attempted using a for loop to categorize fields as 'mandatory' or 'optional', but it still requires duplicating ...

Center-align the text within the dropdown menu

Here is the HTML code snippet I am working on: <select id="ddlCountry" placeholder="optional" class="select" title="Select Country"> <option value="0">country</option> </select> This is how the CSS is set up: .select { width ...

Sending state information through props in a Vuex environment

One of the challenges I am facing is how to make a reusable component that can display data from the store. My idea is to pass the name of the store module and property name through props, as shown below: <thingy module="module1" section=" ...

The process of implementing sticky headers that stay in place while scrolling in a React application

I have a challenge with organizing tables based on date, using headers like (today, yesterday, last week, ...) and I want to make them sticky depending on the current table in the viewport. I attempted to implement this functionality using the react-sticky ...

Looking to add a dynamic divider between two columns that can be adjusted in width by moving the mouse left and right?

If you're looking for an example of two columns adjusting their width based on mouse movement, check out this page from W3Schools. I'm trying to implement this feature in my React app, but I'm unsure of how to proceed. Below is the JSX code ...

A more efficient method for refreshing Discord Message Embeds using a MessageComponentInteraction collector to streamline updates

Currently, I am working on developing a horse race command for my discord bot using TypeScript. The code is functioning properly; however, there is an issue with updating an embed that displays the race and the participants. To ensure the update works co ...

Overlaying a div on top of an iframe

Struggling to make this work for a while now. It seems like a small issue related to CSS. The image isn't overlaying the IFrame at the top of the page as expected, it's going straight to the bottom. Here is the code snippet: .overlay{ width: ...

A guide on updating URLs that are not enclosed within an anchor tag using JavaScript

In my current scenario, I am dealing with text that includes URL links presented in two different formats. www.stackoverflow.com <a href="http://www.stackoverflow.com">Stack over flow</a> My objective is to create a straightforward function ...

The download handler (php code) is being triggered multiple times within a single request

My PHP script is responsible for handling download requests. Clients can access this script using a GET request, as shown in the Javascript example below: if (true) { window.open('/download?mode=paper&fid=' + fid, '_blank'); re ...

Troubleshooting AJAX issues in Firefox with window.location.assign function

Here is my AJAX POST request that sends serialized form data to the server: // Handle form submission. $('#evaluationform').on('submit', function(e){ e.preventDefault(); ajaxObject = { url: $("#evaluationform").attr("a ...

What are some effective methods to completely restrict cursor movement within a contenteditable div, regardless of any text insertion through JavaScript?

Recently, I encountered the following code snippet: document.getElementById("myDiv").addEventListener("keydown", function (e){ if (e.keyCode == 8) { this.innerHTML += "&#10240;".repeat(4); e.preventDefault(); } //moves cursor } ...

Navigate through FAQ items with sliders using Owl Carousel 2 - Easily switch between different chapters

Exploring the creation of a FAQ section with individual carousels for each item. My primary objective is for the carousel to transition to the next chapter when advancing beyond the last slide (backwards navigation would be a future enhancement). I'v ...