Implementing position sticky on a div depending on its content text - step by step guide

If the text inside the .newsDate matches the previous or next .newsDate, I want to make its position sticky when scrolling, until it reaches the next .newsMiddleCont div.

What I'm trying to achieve:

The same date on multiple news items should stick if they were published on the same day.

The current code is not behaving as intended.

It applies and removes the sticky position to all .newsDate elements instead of only when .newsMiddleCont is visible and when the classes have matching innerText.

EDIT:

Further information:

The sticky behavior should be based on the date in .newsDate.

In my example HTML, the first "28. September 2022." should remain sticky until it reaches the second "28. September 2022."; and then continue until "13. October 1999.", after which it becomes static. This process repeats for similar scenarios.

IMPORTANT:

Dates should scroll uniquely. As we scroll down, the date sticks and moves accordingly. If the next article has the same date, the date shifts to that post. If the dates differ, the date stays at the bottom of the corresponding post and scrolls along with it.

Answer №1

It seems like I've grasped the essence of your query... My suggestion is to make a slight modification to the HTML, incorporating writing-mode: vertical-lr; along with transform: rotate(180deg); for the date section.
Below is an example of how your code could be structured:

body {
  padding: 0;
  margin: 0;
  background-color: #1e1e1e;
}

.sec_pub {
  display: grid;
  grid-gap: 64px;
}

.newsCont {
  display: grid;
  grid-template-columns: auto 1fr;
  max-width: 870px;
  color: white;
}

.newsLeftCont {
  writing-mode: vertical-lr;
  transform: rotate(180deg);
  position: sticky;
  top: 20px;
  border-inline-end: solid 1px #fff;
  padding: 20px;
  margin: 0 20px;
  margin-inline: 20px 0;
  white-space: nowrap;
  align-self: start;
  color: #F05663;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  background-color: #1e1e1e;
}

.newsContPosts {
  display: grid;
  grid-gap: 96px;
}

.newsMiddleCont {
  padding: 40px 56px;
  background: #242424;
  display: grid;
  grid-gap: 16px;
}
<section class="sec_pub">
 <div class="newsCont">
    <div class="newsLeftCont">27. September 2022.</div>
    <div class="newsContPosts">
    <div class="newsMiddleCont">
      (Content for the first date)
    </div>
    <div class="newsMiddleCont">
      (Additional content for the first date)
    </div>
  </div>
 </div>
...
</section>

Answer №2

Furthermore, by utilizing the top attribute, you can position the fixed element in a way that gives it the appearance of being sticky. Make sure to adjust your CSS settings accordingly.

$(window).on("scroll", function() {
  // Retrieve all news items.
  let newsItems = $(".newsCont");

  newsItems.each(function(index) {
// Get the current news date.
let currentDate = $(this).find(".newsDate").text().trim();

// Calculate the scroll top position.
let topPosition = $(this).offset().top - $(window).scrollTop();

// If the current date is '28. September 2022.', 
// and the topPosition is less or equal to 0, then add the sticky class.
if (currentDate === '28. September 2022.' && topPosition <= 0) {
  $(this).find(".newsLeftCont").addClass("sticky");
} else {
  // Remove the sticky class otherwise.
  $(this).find(".newsLeftCont").removeClass("sticky");
}
  });
});
html,
body {
  padding: 0;
  margin: 0;
  background-color: #1e1e1e;
}

.newsCont {
  max-width: 870px;
  min-height: 756px;
  position: relative;
  color: white;
}

.newsLeftCont {
  height: 222px;
  padding-top: 40px;
  padding-bottom: 40px;
  left: 0px;
  top: 50px;
  position: absolute;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 8px;
  display: inline-flex;
}

... (remaining CSS code remains the same as original)

.sticky {
  position: sticky;
  top: 0;
  visibility: visible;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="sec_pub">
  <div class="innerWrap newsWrap">
    <div class="newsCont">
      <div class="newsLeftCont">
        <div class="newsLeftContInner">
          <div class="newsDate">28. September 2022.</div>
        </div>
      </div>
      <div class="newsMiddleCont">
        ... (Lorem Ipsum text remains the same as original)
      </div>
    </div>
  </div>
  ... (additional HTML structure remains the same as original)
</section>

Answer №3

I have created a modified version of the problem you provided. These changes are just minor adjustments

$(window).on('scroll', function() {
  var previousDate = null;

  $('.newsLeftCont').each(function() {
    var newsLeftCont = $(this);
    var newsDate = newsLeftCont.find('.newsDate');
    var isElementVisible = isElementInViewport(newsLeftCont);

    newsLeftCont.addClass('sticky');
    
    if (isElementVisible && newsDate.text().trim().toLowerCase() !== previousDate) {
      newsLeftCont.addClass('sticky');
      previousDate = newsDate;
    } else if(previousDate != null) {
      previousDate.removeClass('sticky');
    }
  });
});

function isElementInViewport(element) {
  var rect = element[0].getBoundingClientRect();
  return rect.top >= 0 && rect.bottom <= $(window).height();
}
html,
body {
  padding: 0;
  margin: 0;
  background-color: #1e1e1e;
}

.newsCont {
  max-width: 870px;
  min-height: 756px;
  position: relative;
  color: white;
}

.newsLeftCont {
  height: 222px;
  padding-top: 40px;
  padding-bottom: 40px;
  left: 0px;
  top: 50px;
  position: absolute;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 8px;
  display: inline-flex;
}

.newsLeftContInner {
  align-self: stretch;
  padding-top: 16px;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 8px;
  display: flex;
  height: 160px;
}

.newsDate {
  transform: rotate(-90deg);
  transform-origin: 0 0;
  color: #F05663;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  word-wrap: break-word;
  width: 140px;
  border-right: 0.50px #D6D6D6 solid;
  height: 40px;
  line-height: 37px;
  top: 50px;
  position: relative;
  background-color: #1e1e1e;
}

.newsMiddleCont {
  padding-left: 56px;
  padding-right: 56px;
  padding-top: 40px;
  padding-bottom: 40px;
  left: 76px;
  top: 0px;
  position: absolute;
  background: #242424;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: 16px;
  display: inline-flex
}

.newsLeftCont {
  position: static;
}

.sticky {
  position: sticky;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="sec_pub">
  <div class="innerWrap newsWrap">
    <div class="newsCont">
      <div class="newsLeftCont">
        <div class="newsLeftContInner">
          <div class="newsDate">28. September 2022.</div>
        </div>
      </div>
      <div class="newsMiddleCont">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lectus urna duis convallis convallis tellus id interdum. Sit amet nisl purus in mollis nunc sed id semper. Pharetra magna ac placerat
        vestibulum lectus. Suscipit adipiscing bibendum est ultricies integer quis auctor. Neque ornare aenean euismod elementum nisi quis. Risus nullam eget felis eget nunc lobortis mattis aliquam. Vitae nunc sed velit dignissim sodales ut eu sem. Ullamcorper
        morbi tincidunt ornare massa. Consequat mauris nunc congue nisi. Morbi blandit cursus risus at ultrices mi. Tellus orci ac auctor augue mauris. Id diam vel quam elementum pulvinar etiam non quam lacus. Sem fringilla ut morbi tincidunt augue interdum
        velit euismod. Nulla posuere sollicitudin aliquam ultrices sagittis orci a.<br>Sed augue lacus viverra vitae congue. Molestie ac feugiat sed lectus vestibulum. Venenatis cras sed felis eget velit aliquet sagittis id consectetur. Enim nulla
        aliquet porttitor lacus luctus accumsan tortor posuere. Arcu dictum varius duis at ...

/** Note: The remaining code has been truncated for brevity **/

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

Is there a way to display all of them inline in Woocommerce?

Can anyone assist with making each of these inline? <div class="atc_nsv"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <ul> <li><img class="ad lazyloaded" data-src="//cdn.shopify.com/s/files/1/0608/5882/6972/fi ...

Establish a predetermined selection for a drop-down menu

How can I set a default value for a dynamically filled dropdown menu featuring all 12 months in KnockoutJS? I want the default value to be the current month. This is how I am populating the dropdown with information: self.setMonthData = (data ...

Get immediate results in real-time

On a specific page, I have a form that I want to submit and receive a result upon submission. To display the returned data in a div, I've included this code: <script type="text/javascript"> $(function(){ $('#ff').form ...

"Utilizing AJAX for Data Retrieval in a Form with Dynamically Generated

Hey there, I'm trying to figure out how to make my ajax data call dynamic. Here's what I've attempted: var opt_name = $(".NAME").data('opt_name'); var opt_business = $(".BUSINESS").data('opt_business&ap ...

There are multiple ways to extract a value from Python code and assign it to a JavaScript variable in a JS file

I am currently working on developing the frontend for a voice bot using JavaScript, while the backend is written in Python. if hi == 0: talk('hello iam kavi') print('hello iam kavi Voice assistant') talk('How are you bu ...

`How can you adjust the language preferences for users in Meteor?`

My website is internationalized using the tap-i18n plugin. I am looking to allow users to switch between languages on the site. Currently, I have a file called client/setLanguage.js where I set the language on startup: getUserLanguage = function () { ...

Modify the shading of the mesh generated with the face3 method

I have utilized face 3 and three js to generate a mesh, but the expected color is not displaying correctly on the mesh. Below is the code snippet I used: var geometry = new THREE.Geometry(); var f = 0; for (var i = 0; i < data.real.length ...

What is the reason for npm and yarn to download multiple versions of jquery?

For the purpose of investigating how package managers like npm, yarn, and cnpm work in Node.js, I conducted an experiment. During the test, I came across two packages: jquery-dreamstream and jquery.tree. Both of them have a dependency solely on jquery wit ...

What exactly does the term "library" refer to in the context of jQuery, a JavaScript

I'm confused about the concept of a library - when it comes to jQuery, can it be described as a large file containing multiple plugins that are pre-made and ready for use? ...

Using a loop to format the <ol> tag

After creating an HTML script using angular, I was able to successfully display the names in an array as shown below. <div ng-repeat="namep in names"> <li>Name : <span ng-bind="namep.name"></span></li> <li>Age : ...

React-Native Error: Invalid element type detected

While attempting to run my React Native app on my iPhone using Expo, I encountered an error displayed in a red background area. Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite ...

Transforming JSON data in Node JS according to the city

I currently have a JSON object that contains information about various products and their details in different cities. const data = [ { "city name": "Chennai", "product name": "Apple", ...

Passing data in object as key value after serializing using jQuery AJAX sortable is a common and

Using jquery ui sortable to rearrange a list with php, I extract the ids like this: var ids = $('#sort1').sortable('serialize'); It functions properly when including the ids in the ajax call data like so: data: ids To retrieve it in ...

Gulp does not generate any files

Hey there, I'm brand new to using node.js and coding in general. I recently attempted to convert SCSS to CSS using gulp. My gulpfile.js seems to be correct, but when I try running "gulp styles" in the node.js command prompt, I receive the following ou ...

In the case of a PDF being in landscape orientation, the full width of the document is not utilized despite the width being set to

Even though I have specified the width of the Header table to be 100% and applied a margin-right of 1cm for PDF reports with landscape orientation, the table is not taking up the full width. However, when my PDF report has portrait orientation, the header ...

Configuring IP Whitelisting for Firebase Cloud Functions with MongoDB Cluster

What is the process for including my Firebase Cloud Functions in the IP whitelist of my MongoDB cluster? Error Message: ...

Using CSS units such as vw, vh, or percentage to specify height is not possible

In my Ionic app, I am adjusting the width and height of a div based on the viewport dimensions. This setup functions correctly on the browser and Android 4.4 devices. However, it does not work as expected on Android 4.2 (the height is constrained to the te ...

Having trouble with the toggle button on the Bootstrap 5 navbar?

I am facing an issue with my HTML code where the toggle button does not display properly when I resize the browser screen. Upon clicking on it, the navigation bar items do not show at all. Here is a screenshot of my website <html> <head> ...

Table borders not displaying properly in Chrome when cells are hidden

I'm dealing with a peculiar issue regarding the display of borders in Chrome when individual cells are hidden within an HTML table. The borders disappear, despite being defined for the row and table elements. Does anyone have experience with this spec ...

HTML video audio playing, but screen remains empty

I am facing an issue while trying to watch a video using HTML. The audio plays, but the video remains blank. The video is in MP4 format and can be found at this link. Interestingly, it works when downloaded and viewed, as my friend created it. I even tried ...