Place the child atop the stacked blocks

I need the .square div to always remain at the top, creating a visual effect where it appears as if the following section with its own .square is sliding up and the .square halts precisely at the position of the previous section's square.

The code snippet below achieves this effect:

$(document).ready(function() {
  const sections = document.querySelectorAll('.make-sticky');

  // Intersection Observer
});
});
.scrollable {
  border: 5px solid red;
  position: relative;

    // CSS Styling for sticky elements

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.2/jquery.min.js"></script>
        <div class="scrollable">
            <section class="make-sticky" style="background: cyan" id="section1">
                <div class="line"></div>
                <div class="square"></div>
                <p>Lorem ipsum dolor sit amet...</p>
            </section>

            // Additional Sections

        </div>

However, the next section covers the previous square when it "slides up". Despite no z-index being defined on any parent element of my code, using it still does not resolve the issue.

What steps can be taken to address this problem and ensure proper functionality?

https://i.sstatic.net/61zFZWBM.png

https://i.sstatic.net/repRn5kZ.png

Answer №1

I included a "floating-square" element that appears when the initial "make-sticky" section reaches the top of the window and disappears when the last section does the same.

$(document).ready(function() {
  const sections = document.querySelectorAll('.make-sticky');
  const floatingSquare = $('.floating-square');
  let scrollingDown = true;

  // Function to update floatingSquare visibility
  function updateFloatingSquareVisibility() {
    const firstSection = sections[0];
    const lastSection = sections[sections.length - 1];

    const firstSectionRect = firstSection.getBoundingClientRect();
    const lastSectionRect = lastSection.getBoundingClientRect();

    if (scrollingDown) {
      if (firstSectionRect.top <= 0) {
        floatingSquare.show();
      }
      if (lastSectionRect.top <= 25) {
        floatingSquare.hide();
      }
    } else {
      if (lastSectionRect.top > 25) {
        floatingSquare.show();
      }
      if (firstSectionRect.top > 0) {
        floatingSquare.hide();
      }
    }
  }

  // Intersection Observer to monitor sections
  const observer = new IntersectionObserver(entries => {
    entries.forEach(({ target, isIntersecting }) => {
      if (isIntersecting) {
        $(target).addClass('sticky-section');
      } else {
        $(target).removeClass('sticky-section');
      }
    });
  }, {
    root: null,
    rootMargin: '0px',
    threshold: [0, 0.25] // Trigger when 25% of the element is visible
  });

  sections.forEach((section) => {
    observer.observe(section);
  });

  // Event listener for scroll to determine scroll direction
  let lastScrollTop = 0;
  $(window).on('scroll', function() {
    const scrollTop = $(this).scrollTop();
    scrollingDown = scrollTop > lastScrollTop;
    lastScrollTop = scrollTop;
    updateFloatingSquareVisibility();
  });

  // Initial check for visibility
  updateFloatingSquareVisibility();
});
.scrollable {
  border: 3px solid darkblue;
  position: relative;

  .make-sticky {
    position: relative;
    height: 100vh;
    padding: 20px;
    box-sizing: border-box;
    margin-top: -22px;
    z-index: 1;

    .line {
      position: absolute;
      left: 20px;
      top: 0;
      bottom: 0;
      width: 2px;
      background: black;
    }

    ......(more CSS code)

</div>

Answer №2

To achieve this effect, you can start by creating a separate container using the div tag to hold all the squares or headers. This container should cover the entire scrollable area within your layout. Then, utilize the margin property on each square to align it correctly with its corresponding section.

In order to ensure that the squares adjust automatically when the height of the sticky sections changes, custom CSS variables are utilized. By updating the height variable, the positioning of the squares will be maintained without manual adjustments.

Given that the squares are meant to be in sequence and overlap accordingly, there is no need for the use of z-index. However, if you desired specific overlapping behavior, z-index could be applied as necessary.

Keep in mind that when using position: sticky, left/right positioning becomes invalid once the element becomes "stuck." Therefore, rely on the margin properties to position the square elements effectively.

:root {
  --sticky-section-height: 100vh;
}

* {
  box-sizing: border-box;
}

.scrollable {
  border: 5px solid red;
  position: relative;
}

.make-sticky {
  height: var(--sticky-section-height);
  box-sizing: border-box;
  border-bottom: 1px solid green;
  padding: 10px;
  background-color: var(--clr);
  position: relative;
}

.line {
  position: absolute;
  left: 20px;
  top: 0;
  bottom: 0;
  width: 2px;
  height: 100%;
  background: black;
}

.sticky-container {
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  z-index: 10;
  border: 2px solid rgb(0, 21, 255);
}

.square {
  position: sticky;
  color: white;
  top: 0px;
  /* Margin used to position the element horizontally*/
  margin-left: 10px;
  margin-bottom: calc((var(--sticky-section-height) - 20px));
  width: 20px;
  height: 20px;
  background: black;
  border: 2px solid red;
  /* Adjust this percentage based on your design */
}

p {
  margin-top: 50vh;
  /* Center text vertically */
}
<div class="scrollable">

  <div class="sticky-container">
    <div class="square">1</div>
    <div class="square">2</div>
    <div class="square">3</div>
  </div>

  <section class="make-sticky" style="--clr: green" id="section1">
    <div class="line"></div>
    <p>Lorem ipsum dolor sit amet</p>
  </section>

  <section class="make-sticky" style="--clr: orange" id="section2">
    <div class="line"></div>
    <p>Quod magni natus dignissimos</p>
  </section>

  <section class="make-sticky" style="--clr: cyan" id="section3">
    <div class="line"></div>
    <p>Quod magni natus dignissimos</p>
  </section>
</div>

Answer №3

Not entirely sure if this is exactly what you had in mind, but it might bring you close to the solution.

.scrollable {
  border: 5px solid red;
  position: relative;
}

.make-sticky {
  position: relative;
  height: 100vh;
  padding: 20px;
  box-sizing: border-box;
}

.line {
  position: absolute;
  left: 20px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: black;
}

.square {
  position: sticky;
  top: 25%;
  left: 10px;
  width: 20px;
  height: 20px;
  background: transparent;
  border: 2px solid red;
  z-index: 10; 
}

.make-sticky p {
  margin-top: 50vh; 
}
<div className="scrollable">
    <section class="make-sticky" id="section1">
      <div class="line"></div>
      <div class="square"></div>
      <p>Lorem ipsum dolor sit amet</p>
    </section>

    <section class="make-sticky" id="section2">
      <div class="line"></div>
      <div class="square"></div>
      <p>Quod magni natus dignissimos</p>
    </section>

    <section class="make-sticky" id="section3">
      <div class="line"></div>
      <div class="square"></div>
      <p>Quod magni natus dignissimos</p>
    </section>
  </div>

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

Using lazy loading and $ocLazyLoad for improved performance

Recently, I stumbled upon the $ocLazyLoad third-party Angular module that allows for the lazy loading of JavaScript files. This concept has me a bit perplexed. Can you explain the difference between lazy loading and caching, and why one would choose to l ...

Using Jquery to make multiple elements sticky and float

Is it possible to have multiple stickyfloat elements that follow each other up? For example, I have multiple articles with large images and I would like the description to stay sticky until you reach the next article. Currently, all the stickyfloat elemen ...

Showing nested routes component information - Angular

I am working on a project that includes the following components: TodosComponent (path: './todos/'): displaying <p>TODO WORKS</p> AddTodosComponent (path: './todos/add'): showing <p>ADD TODO WORKS</p> DeleteTo ...

Issue with Jquery Date picker functionality on Master Page not functioning as expected

My issue is with the master page <%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1- ...

What can I do to keep my navbar on top of the slideshow?

https://i.sstatic.net/SfiLZ.jpg Is there a way to create a responsive navbar that sits in front of a slideshow containing images? I attempted to place the div within the main, but unfortunately it was unsuccessful. ...

Add C# iteration with JavaScript on ASP.NET directories

I need help extracting all filenames from a specific folder on the server, and then adding them to a JavaScript array. The functionality should mimic ASP.NET C#'s Directory.GetFiles method. I have already initialized an array and now just require as ...

Close the ionicPopup by tapping anywhere

Currently, I have implemented an ionicPopup that automatically closes after a certain time limit. However, I am wondering if there is a way to configure it to close with a single or double tap anywhere on the screen instead. While I am aware that setting a ...

Issue with InversifyJS @multiInject: receiving an error stating "ServiceIdentifier has an ambiguous match"

Having an issue with inversifyJs while trying to implement dependency injection in my TypeScript project. Specifically, when using the @multiInject decorator, I keep receiving the error "Ambiguous match found for serviceIdentifier". I've been referenc ...

Update Symfony form class to replace the HTML5 input type from "text" to "number"

Attempting to implement an input with the "number" type for HTML5 frontend support has been a challenge. Here is my form class: class MyType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { ...

Can Jest Vue handle loading dynamic imports for snapshot testing?

Having an issue with unit testing a Vue component that dynamically loads its child component. Jest and Vue utils don't seem to render it. Any suggestions on how to tackle this? Here's the component code: <template> <component :is=&quo ...

Using ajax to submit variables may not function properly

I have a set of data that has been processed using JavaScript and I am looking to save it to a database. I have been attempting to code something with AJAX, but so far, I have had no success... What I require: Two variables (id, name) need to be sent to a ...

Obtaining the Camera's Position Relative to the Origin in Three.js

The wording of this question might be unclear, but I'm struggling to phrase it concisely. Here's the scenario: there is a perspective camera in the scene along with a mesh. The mesh is positioned away from the origin of the axis. The camera is ...

Ways to delete scheduled tasks in BreeJS

I am currently working on an express server that initiates a recurring job upon client request for a specific duration. The challenge I am encountering is figuring out how to stop and remove that particular job once it has been completed. The following is ...

Ways to address the absence of the 'Access-Control-Allow-Origin' header on the requested resource

CORS: Dealing with Cross-Origin Resource Sharing (CORS) can be a common challenge for developers, and it's something I've encountered myself when trying to access a REST service from a different domain. When this issue arises, the error message ...

Building Vertical Tabs with external JS for loading custom visuals

I am trying to figure out how to display the visuals I created in an alternate page within my Vertical tabs. The tabs are already styled, and I have omitted the CSS due to its length. The HTML file I am working with is test.html, and the visuals are in the ...

The columns in CSS grid-template are refusing to change despite the media query code being applied and active

Currently, I am facing an issue while working on a site plugin and trying to utilize CSS grid to showcase posts. Despite the media query being active according to the inspector, the modification in the template columns is not reflecting as expected. Check ...

Interact with elements on a dynamically loaded webpage using Selenium WebDriver in Java

I am faced with a challenge of clicking on a specific element on a dynamically loaded page, where the web element is generated as we scroll down the page, similar to the setup on a Jabong webpage. Here is the code I tried on the Jabong webpage: WebDrive ...

Creating custom functions within views using Sencha Touch 2

I'm having trouble creating my own function in Sencha Touch 2 and I keep receiving an error: Uncaught ReferenceError: function22 is not defined The issue seems to be coming from my Position.js file located in the View directory. Ext.define(' ...

The functions domElement.getClientWidth() and domElement.getClientHeight() are returning a value of 0

When trying to extract the size of a GWT element with a specific CssClass using standard methods, I am faced with the issue that it returns 0; Canvas canvas = Canvas.createIfSupported(); if(canvas == null){ /*alert code*/ } Element ...

Steps to properly insert an SVG into a button

I have a block set up with a Link and added text along with an svg image inside. How can I properly position it to the lower right corner of the button? (see photo) Additionally, is there a way to change the background color of the svg? This is within th ...