Search code examples
htmlcssscrollsticky

Scrolling two DIVs with different height; one waits for the other


So in an HTML document I have two DIVs side by side, each with a different height. When the user starts scrolling down, both DIVs should start scrolling at the same time, as you would expect. When the end of the shorter DIV is reached, it should stick to the bottom of the viewport until the end of the taller DIV is reached. The page should then continue to scroll "normally". Here is the starting point:

.parent {
  display: flex
}

.child {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.left {
  background: lightblue;
  height: 200vh;
}

.right {
  background: lightcoral;
  height: 120vh;
}
<div class="parent">
  <div class="child left">
    <div>Top</div>
    <div>Bottom</div>
  </div>
  <div class="child right">
    <div>Top</div>
    <div>Bottom</div>
  </div>
</div>

After fiddling around for some time, I can only achieve the exact opposite of what I try to accomplish:

.parent {
  display: flex
}

.child {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.left {
  background: lightblue;
  height: 200vh;
}

.right {
  background: lightcoral;
  height: 120vh;
  position: sticky;
  top: 0;
}
<div class="parent">
  <div class="child left">
    <div>Top</div>
    <div>Bottom</div>
  </div>
  <div class="child right">
    <div>Top</div>
    <div>Bottom</div>
  </div>
</div>

Any help would be appreciated.


Solution

  • Derived this from @Wongjn’s great solution, using Javascript to calculate the top values for the child divs.

    const randomIntFromInterval = (min, max) => {
      return Math.floor(Math.random() * (max - min + 1) + min)
    }
    
    const d1 = document.querySelectorAll('.d1>*').forEach(c => {
      const q = randomIntFromInterval(50,250)
      c.style.height = q + 'vh'
      c.style.top = (100 - q) + 'vh'
      c.children[1].innerHTML = 'height: ' + c.style.height + '<br>top: ' + c.style.top
    })
    .d1 {
      display: flex;
    }
    
    .d1>* {
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      position: sticky;
      padding: 1em;
      box-sizing: border-box;
    }
    
    .d1>*:nth-child(1) {
      background: lightblue;
    }
    
    .d1>*:nth-child(2) {
      background: lightcoral;
    }
    
    .d1>*:nth-child(3) {
      background: lightgreen;
    }
    
    .d1>*:nth-child(4) {
      background: bisque;
    }
    <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas tempor nunc mauris, sit amet placerat tortor lobortis dapibus. Nam lectus eros, maximus ac magna vel, congue consequat eros. Fusce id pretium diam. Cras sit amet pharetra ante. Sed quis commodo quam, vel facilisis ipsum. Vestibulum sodales iaculis arcu, et fringilla nisi ullamcorper sed. Donec interdum sit amet est non accumsan. Donec non augue feugiat, fermentum nunc non, convallis est. Cras vel ligula nec odio faucibus ultricies. Sed vulputate tortor eget pretium convallis. Cras interdum elit eget mi porta suscipit. Morbi ut velit diam. Etiam finibus eros et efficitur rutrum. Quisque viverra metus ac eleifend imperdiet. Quisque pretium ut purus vitae tempus. Duis varius risus congue velit faucibus, sed interdum purus consectetur.
    </p>
    
    <div class="d1">
      <div>
        <div>Top</div>
        <div>Middle</div>
        <div>Bottom</div>
      </div>
      <div>
        <div>Top</div>
        <div>Middle</div>
        <div>Bottom</div>
      </div>
      <div>
        <div>Top</div>
        <div>Middle</div>
        <div>Bottom</div>
      </div>
      <div>
        <div>Top</div>
        <div>Middle</div>
        <div>Bottom</div>
      </div>
    </div>
    
    <p>
    Cras volutpat velit non mi sagittis condimentum. Cras tempor aliquet turpis sed pretium. Nunc aliquet sodales turpis quis ultrices. Duis auctor accumsan enim, quis maximus ex malesuada a. Donec a felis ut erat tempus euismod non vel neque. Proin lectus massa, sagittis at imperdiet nec, consequat ut neque. Sed vel placerat neque, vel varius urna. Vivamus interdum euismod urna a accumsan. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
    </p>