skip to Main Content

I have two article tags positioned as absolute and I want to transition between them using a fade effect.

I am using opacity and z-index to achieve this.

The problem I am having is that when the article behind the active one has content that makes it higher than the one in front when the page scrolls it becomes visible, the only way to avoid that is to use display: none or overflow: hidden but this makes the page either not fadable or not scrollable.

I got this:

// When clicking on a next button change the active class
document.querySelector('#next').addEventListener('click', function() {
  document.querySelector('.active').classList.remove('active')
  document.querySelector('#about').classList.add('active')
})
html, body, main {
  height: 100%;
}

main {
  position: relative;
  height: 100%;
  width: 100%;
  overflow: auto;
}

body {
 background: pink;
 padding: 0;
 margin: 0;
}


.content {
  display: table-cell;
  vertical-align: middle
}

.container {
  max-width: 500px;
  margin: 0 auto;
  position: relative;
  overflow: hidden;
}

article {
  display: table;
  width: 100%;
  height: 100%;
  background: no-repeat fixed bottom / cover;
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  z-index: -1;
  transition: opacity 0.3s ease;
  background-color: #fff;
}

article.active {
  opacity: 1;
  z-index: 1;
}
<html lang="en">
<body>
<main>

  <article id='intro' class='active'>
    <div class='content'>
      <div class='container'>
        This is the front page
        
        <button id='next'>Next</button>
        <br><br><br><br><br><br><br><br><br><br>
      </div>
    </div>
  </article>

  <article id='about'>
    <div class='content'>
      <div class='container'>
         This is the page behind the front that I cannot hide cause its content makes it higher
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> <br><br><br><br><br><br>
      </div>
    </div>
  </article> 
</main>
</body>
</html>

You can see the body background-color: pink when scrolling caused by the height of the about article

2

Answers


  1. Looks like it can be solved using 100vh for the heights

    // When clicking on a next button change the active class
    document.querySelector('#next').addEventListener('click', function() {
      document.querySelector('.active').classList.remove('active')
      document.querySelector('#about').classList.add('active')
    })
    html, body, main {
      height: 100vh;
    }
    
    main {
      position: relative;
      height: 100vh;
      width: 100vw;
      overflow: auto;
    }
    
    body {
     background: pink;
     padding: 0;
     margin: 0;
    }
    
    
    .content {
      display: table-cell;
      vertical-align: middle
    }
    
    .highDemo {
      height: 110vh;
    }
    
    .container {
      max-width: 500px;
      margin: 0 auto;
      position: relative;
      overflow: hidden;
    }
    
    article {
      display: table;
      width: 100%;
      height: 100%;
      background: no-repeat fixed bottom / cover;
      position: absolute;
      top: 0;
      left: 0;
      opacity: 0;
      z-index: -1;
      transition: opacity 0.3s ease;
      background-color: #fff;
    }
    
    article.active {
      opacity: 1;
      z-index: 1;
    }
    <html lang="en">
    <body>
    <main>
    
      <article id='intro' class='active'>
        <div class='content'>
          <div class='container'>
            This is the front page
            <button id='next'>Next</button>
          </div>
        </div>
      </article>
    
      <article id='about'>
        <div class='content'>
          <div class='container'>
             This is the page behind the front that I cannot hide cause its content makes it higher
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
             <p></p>
          </div>
        </div>
      </article> 
    </main>
    </body>
    </html>
    Login or Signup to reply.
  2. You need to set all .article to the highest height. Something like this:

    setArticlesHeight()
    window.onresize = setArticlesHeight;
    
    function setArticlesHeight(){
      let largeHeight = 0;
      document.querySelectorAll('article').forEach(el => el.style.removeProperty('height'));
      document.querySelectorAll('article').forEach(el => {
        if ( el.scrollHeight > largeHeight ){
          largeHeight = el.scrollHeight;
        }
      })
      document.querySelectorAll('article').forEach(el => el.style.height = largeHeight + 'px');
    }
    
    document.querySelectorAll('.next').forEach(btn => {
      btn.onclick = () => {
        const activeArticle = document.querySelector('.active');
        document.querySelectorAll('article').forEach(el => el.classList.remove('active'));
        activeArticle.nextElementSibling.classList.add('active');
      }
    })
    
    document.querySelectorAll('.prev').forEach(btn => {
      btn.onclick = () => {
        const activeArticle = document.querySelector('.active');
        document.querySelectorAll('article').forEach(el => el.classList.remove('active'));
        activeArticle.previousElementSibling.classList.add('active');
      }
    })
    html,
    body {
      height: 100%;
    }
    
    body {
      background: pink;
      padding: 0;
      margin: 0;
    }
    
    main {
      position: relative;
      height: 100%;
      overflow: auto;
    }
    
    article {
      inset: 0;
      position: absolute;
      transition: opacity .4s, visibility .4s;
    }
    
    article:not(.active) {
      opacity: 0;
      visibility: hidden;
    }
    
    #intro {
      background-color: lightblue;
    }
    
    #about {
      background-color: lightgreen;
    }
    
    .content {
      display: grid;
      place-items: center;
    }
    
    .container {
      width: 500px;
      max-width: 100%;
    }
    <main>
      <article id="intro" class="active">
        <div class="content">
          <div class="container">
            This is the front page
            <button class="next">Next</button>
          </div>
        </div>
      </article>
      <article id="about">
        <div class="content">
          <div class="container">
            <button class="prev">Prev</button>
            This is the page behind the front that I cannot hide cause its content makes it higher
            <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> <br><br><br><br><br><br>
          </div>
        </div>
      </article> 
    </main>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search