title: Parallax effects on multiple banner images (Without Using Background Image)
body: <p>I'm building parallax banner images with text overlays and <strong>I DON'T want to use css. background images</strong> to make this happen as I'm building a Wordpress Theme that can be altered by the client.</p>
  <p>Instead, I'd like to keep the <strong>DIV</strong> with the image overlay (and text), positioned relative in the document flow and set it a height of around 450px for this, and have the associated image behind it in another <strong>DIV positioned absolute</strong> that moves in a parallax manor on scroll.</p>
  <p>So... As the page scrolls up/down, the image behind moves up/down with it, but at a slower pace, still <strong>RELATIVE TO ITS PARENT DIV</strong>.</p>
  <p>I can do it with 1 image per page.
  BUT, when I add more I need the pageYOffset on the 2nd and 3rd images to ONLY begin moving the image, when the parent DIV enters the viewport at the bottom of the screen.</p>
  <p>As such I've tried many JS solutions including my last go, using intersection observers, to try to stop the later parallaxes from starting early but to no avail...</p>
  <p>Any help please...</p>
  <p><strong>Here's the mark up</strong></p>
  <pre><code>    &lt;!-- First Parallax Content --&gt;
      &lt;div id=&quot;parallaxOne&quot; class=&quot;parallax-content-container&quot;&gt;
          &lt;!-- Banner Image --&gt;
          &lt;div id=&quot;parallaxTargetOne&quot; class=&quot;parallax-image-wrapper&quot;&gt;
              &lt;img src=&quot;IMG&quot;alt=&quot;ALT&quot;&gt;
          &lt;/div&gt;
          &lt;div class=&quot;inner-wrapper contained-content&quot;&gt;
              &lt;div class=&quot;quote-container&quot;&gt;
                  &lt;!-- Featured Title --&gt;
                  &lt;h2&gt;FEATURED TITLE&lt;/h2&gt;
                  &lt;!-- Sub Title --&gt;
                  &lt;h3&gt;SUB TITLE&lt;/h3&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  
      &lt;!-- Second Parallax Content --&gt;
      &lt;div id=&quot;parallaxTwo&quot; class=&quot;parallax-content-container&quot;&gt;
          &lt;!-- Banner Image --&gt;
          &lt;div id=&quot;parallaxTargetTwo&quot; class=&quot;parallax-image-wrapper&quot;&gt;
              &lt;img src=&quot;IMG&quot;alt=&quot;ALT&quot;&gt;
          &lt;/div&gt;
          &lt;div class=&quot;inner-wrapper contained-content&quot;&gt;
              &lt;div class=&quot;quote-container&quot;&gt;
                  &lt;!-- Featured Title --&gt;
                  &lt;h2&gt;FEATURED TITLE&lt;/h2&gt;
                  &lt;!-- Sub Title --&gt;
                  &lt;h3&gt;SUB TITLE&lt;/h3&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  </code></pre>
  <p><strong>Here's the simple css</strong></p>
  <pre><code>.parallax-content-container {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 450px;
      // overflow: hidden;
      border: 8px dotted green; // To See The Problem
  }
  .parallax-image-wrapper {
      position: absolute;
      height: 100vh;
      width: 100%;
      top: 0;
      left: 0;
      z-index: -1;
      border: 10px solid red; // To See The Problem
  }
  .parallax-image-wrapper:after {
      content: '';
      position: absolute;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      background: rgba(0, 0, 0, 0.025);
  }
  .parallax-image-wrapper &gt; img {
      height: 100%;
      object-fit: cover;
      object-position: center center;
  }
  .quote-container h2,
  .quote-container h3 {
      color: #fff;
      text-shadow: 0 0 30px rgba(0, 0, 0, 0.8);
  }
  </code></pre>
  <p><strong>Heres my JS | The First Way I Tried</strong></p>
  <pre><code>const parallaxOne = document.getElementById('parallaxOne');
  const parallaxTwo = document.getElementById('parallaxTwo');
  
  window.addEventListener('scroll', function (event) {
      if (parallaxOne.getBoundingClientRect().top &lt; window.innerHeight) {
          const firstParallaxEffect = element1 =&gt; {
              console.log('In the viewport');
              let scrolled = window.pageYOffset;
              let rate = scrolled * -0.175;
              element1.style.top = window.pageYOffset;
              element1.style.transform = 'translate3d(0px, ' + rate + 'px, 0px)';
          };
          firstParallaxEffect(document.getElementById('parallaxTargetOne'));
      }
  
      if (parallaxTwo.getBoundingClientRect().top &lt; window.innerHeight) {
          const secondParallaxEffect = element =&gt; {
              console.log('In the viewport');
              let scrolled = window.pageYOffset;
              let rate = scrolled * -0.175;
              element.style.top = window.pageYOffset;
              element.style.transform = 'translate3d(0px, ' + rate + 'px, 0px)';
          };
          secondParallaxEffect(document.getElementById('parallaxTargetTwo'));
      }
  });
  </code></pre>
  <p><strong>The Second Way I Tried</strong></p>
  <pre><code>const parallaxOne = document.getElementById('parallaxOne');
  const elementOne = document.getElementById('parallaxTargetOne');
  const optionsOne = {
      root: null,
      threshold: 0,
      rootMargin: '0px',
  };
  const parallaxTwo = document.getElementById('parallaxTwo');
  const elementTwo = document.getElementById('parallaxTargetTwo');
  const optionsTwo = {
      root: null,
      threshold: 0,
      rootMargin: '0px',
  };
  
  const obsOne = new IntersectionObserver(function (entries, obsOne) {
      entries.forEach(entry =&gt; {
          window.addEventListener('scroll', function (event) {
              let scroll = window.pageYOffset;
              let rate = scroll * -0.17;
              elementOne.style.transform =
                  'translate3d(0px, ' + rate + 'px, 0px)';
          });
      });
  }, optionsOne);
  obsOne.observe(parallaxOne);
  
  const obsTwo = new IntersectionObserver(function (entries, obsTwo) {
      entries.forEach(entry =&gt; {
          window.addEventListener('scroll', function (event) {
              let scroll = window.pageYOffset;
              let rate = scroll * -0.17;
              elementTwo.style.transform =
                  'translate3d(0px, ' + rate + 'px, 0px)';
          });
      });
  }, optionsTwo);
  obsTwo.observe(parallaxTwo);
  </code></pre>
  <p><a href="https://i.stack.imgur.com/ooPfT.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ooPfT.jpg" alt="enter image description here" /></a></p>