css 两个不同高度的绝对div之间的淡入淡出过渡

oknwwptz  于 2023-06-07  发布在  其他
关注(0)|答案(2)|浏览(179)

我有两个article标记定位为绝对,我想使用渐变效果在它们之间转换。
我使用opacityz-index来实现这一点。
我遇到的问题是,当活动文章后面的文章内容高于前面的文章时,当页面滚动时,它变得可见,避免这种情况的唯一方法是使用display: noneoverflow: hidden,但这使得页面不可褪色或不可滚动。
我得到了这个

// 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>

你可以看到身体background-color: pink滚动时造成的高度的文章

ngynwnxp

ngynwnxp1#

我建议合并换两个班。例如,'active' class设置article的高度,而visible class使article可见:

document.querySelectorAll('.next').forEach( btn => btn.onclick = () => changeArticle('next') )
document.querySelectorAll('.prev').forEach( btn => btn.onclick = () => changeArticle('prev') )

function changeArticle(direction) {
  const activeArticle = document.querySelector('.active');
  const elementSibling = direction === 'next' ? 'nextElementSibling' : 'previousElementSibling';
  const nextArticle = activeArticle[elementSibling];
  activeArticle.classList.remove('visible');
  nextArticle.classList.add('visible');
  /* transition-duration delay */
  setTimeout(() => {
    activeArticle.classList.remove('active')
    nextArticle.classList.add('active');
  }, 400);
}
html,
body {
  height: 100%;
}

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

main {
  position: relative;
  height: 100%;
  overflow-y: scroll;
}

article {
  inset: 0;
  position: absolute;
  transition: opacity .4s, visibility .4s;
  min-height: 100%;
  height: max-content;
  display: grid;
  place-items: center;
}

article:not(.active) {
  height: 0;
  overflow: hidden;
}

article:not(.visible) {
  opacity: 0;
  visibility: hidden;
}

#intro {
  background-color: lightblue;
}

#about {
  background-color: lightgreen;
}

.content {
  width: min(500px, 100%);
  padding: 40px 20px;
}
<main>
  <article id="intro" class="active visible">
    <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>

或者您可以将所有.article设置为最高的height。就像这样:

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 = () => goToArticle('next') )

document.querySelectorAll('.prev').forEach( btn => btn.onclick = () => goToArticle('prev') )

function goToArticle(direction) {
  const activeArticle = document.querySelector('.active');
  document.querySelectorAll('article').forEach(el => el.classList.remove('active'));
  if(direction === 'next') {
    activeArticle.nextElementSibling.classList.add('active');
  }
  if(direction === 'prev') {
    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>
nsc4cvqm

nsc4cvqm2#

看起来可以使用100vh来解决高度问题
基于我的评论:这就是我所说的“简化”:

document.addEventListener('click', (evt) => {
  if (evt.target.closest(`button`)) {
    const nxt = evt.target.closest(`button`).dataset.next;
    document.querySelector('.active').classList.remove('active');
    return document.querySelector(nxt).classList.add('active');
  }
})
body {
  margin: 0;
  font-family: system-ui, sans-serif;
}

/* for creating space in demo */
article div p {
  min-height: 1.2rem;
}

article {
  position: absolute;
  width: 100vw;
  left: 50%;
  height: 0;
  transform: translateX(-50%);
  background-color: rgb(245, 191, 200);
  transition: background-color 0.5s ease;
}

article div {
  position: absolute;
  z-index: -1;
  opacity: 0;
  max-height: 100vh;
  max-width: 75%;
  top: 50%;
  left: 50%;
  overflow: auto;
  transform: translate(-50%, -50%);
  background-color: rgb(245, 191, 200);
  transition: opacity, background-color 0.5s ease;
}

article.active {
  top: 0;
  bottom: 0;
  height: auto;
  background-color: #FFF;
}

article.active div {
  z-index: 2;
  opacity: 1;
  background-color: #FFF;
}
<main>
  <article class="active" id="intro">
    <div>
      This is the front page
      <button data-next="#about">Next</button>
    </div>
  </article>

  <article id="about">
    <div>
      This is the page behind the front that I cannot 
      hide cause its content makes it higher
      <button data-next="#intro">Previous</button>
      <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>THE LAST PARAGRAPH</p>
    </div>
  </article>
</main>

相关问题