skip to Main Content

I have been banging my head against this for a while now.
Essentially I have a sticky button that follows the user as they are reading text. The button when clicks expands into a set of options, which also follow the user. At the bottom of the page however this looks bad, as the options can run off screen. (I cannot use overflow:hidden on the textbox).
I am solving this with an IntersectionObserver, where once the button goes past the box "container", I want it to disappear (right now i have it turning blue for debugging purposes). But this is not working as expected. The IntersectionObserver triggers at the top of the page, and at the bottom, but not when scrolling past the "container"! See here:

const root = document.querySelector('#root');
const target = document.querySelector('#target');

const options = {
  root: root,
  rootMargin: '0px',
  threshold: 1
};
let observer = new IntersectionObserver(handleIntersection, options)


function handleIntersection (entries) {
  if (entries[0].isIntersecting) {
    target.classList.add("vis-none")
  } else {
   target.classList.remove("vis-none")
  }
}

observer.observe(target);
.container{
  height:2000px;
  width:500px;
  position:relative;
  background:repeating-linear-gradient(
    0deg,
    #ffffff 19px,
    #eeeeee 20px,
    #eeeeee 30px,
    #ffffff 31px);
  padding:1rem;
  margin-bottom:1000px;
}

.sticky-row{
  position:sticky;
  top:1rem;
  right:1rem;
}

.absolute{
  position:absolute;
}

.relative{
  position:relative;
}

.vis-none{
  color:blue;
}
<div id="root", class="container">
  <div class="sticky-row">
    <div class="absolute">
      <div id="target", class="relative">
        <p> pretend this is a row of buttons with an expandable area
        <p> expandable area
        <p> expandable area
        <p> expandable area
        <p> expandable area
      </div>
    </div>
  </div>
  
</div>

What am I doing wrong???

2

Answers


  1. Chosen as BEST ANSWER

    Well I found the answer, I'm not sure why it works though. I turned the threshold to 0.9. The threshold is the % overlap that triggers isIntersecting. 1.0 should have worked as far as i can tell, but... well 0.9 works, so cool.


  2. No need for js, you had a CSS issue; you had a position relative inside a position absolute not sure why. but that caused the .sticky-row div to have a height of 0px and the actual content was overflowing.
    I discovered that buy adding some outlines for debugging, is this the behavior you’re looking for?

    .container{
      height:2000px;
      width:500px;
      position:relative;
      background:repeating-linear-gradient(
        0deg,
        #ffffff 19px,
        #eeeeee 20px,
        #eeeeee 30px,
        #ffffff 31px);
      padding:1rem;
      margin-bottom:1000px;
      outline:1px solid black;
    }
    
    .sticky-row{
      position:sticky;
      top:1rem;
      right:1rem;
      outline:1px solid red;
      height:200px; /*edit this to your needs*/
    }
    
    .absolute{
      position:absolute;
      outline:1px solid green;
    }
    
    .relative{
      position:relative;
      outline:1px solid cyan;
    }
    
    .vis-none{
      color:blue;
    }
    <div id="root", class="container">
      <div class="sticky-row">
        <div class="absolute">
          <div class="relative" id="target">
            <p> pretend this is a row of buttons with an expandable area </p>
            <p> expandable area </p>
            <p> expandable area </p>
            <p> expandable area </p>
            <p> expandable area </p>
          </div>
        </div>
      </div>
      
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search