Search code examples
javascriptcssslideshowfade

CSS Fade Delay?


I'm trying to create a slideshow banner for my website, and my idea was to stack them using z-index, then have the one on top fade out to reveal the one beneath, then move itself to the bottom of the stack.

I didn't fully understand how the CSS fade rules would work, and it seems they are fading all images in the stack at once, rather than just the one on top. Is there an elegant way to make the fade class follow the top image of the stack so it's only fading out when it's on top?

Any help would be appreciated...

var slidePosition = 0;
fadeSlides();


function fadeSlides() {
  var i;
  var slide = document.getElementsByClassName("mySlides");
  for (i = 0; i < slide.length; i++) {
    slide[i].style.zIndex = slide[i].style.zIndex + 1;
    slide[i].style.opacity = "1";
  }
  slidePosition++;
  if (slidePosition > slide.length) {
    slidePosition = 1
  }
  slide[slidePosition - 1].style.opacity = "0";
  slide[slidePosition - 1].style.zIndex = "0";
  setTimeout(fadeSlides, 3500);

}
.slideshow-container {
  width: 100%;
  position: relative;
}

.mySlides {
  opacity: 1;
  position: absolute;
}

.fade {
  animation: fade 1s infinite;
}

@keyframes fade {
  0% {
    opacity: 1
  }
  100% {
    opacity: 0
  }
}
<div class="slideshow-container">

  <div class="mySlides fade" style="z-index: 5">
    <img src="https://i.imgur.com/h9HMwvD.png" style="width:100%">
  </div>

  <div class="mySlides fade" style="z-index: 4">
    <img src="https://i.imgur.com/inAYNo3.png" style="width:100%">
  </div>

  <div class="mySlides fade" style="z-index: 3">
    <img src="https://i.imgur.com/8VHulyg.png" style="width:100%">
  </div>

  <div class="mySlides fade" style="z-index: 2">
    <img src="https://i.imgur.com/wZzx8GU.png" style="width:100%">
  </div>

  <div class="mySlides fade" style="z-index: 1">
    <img src="https://i.imgur.com/ZPO4z3V.png" style="width:100%">
  </div>

  <div class="mySlides fade" style="z-index: 0">
    <img src="https://i.imgur.com/yhuKaY8.png" style="width:100%">
  </div>

</div>


Solution

  • Temani Afif's answer will help make things look good with your current approach, but the more simple answer is, as others have commented, to just toggle a class on one slide at a time.

    You can use the CSS transition property to do this a bit more simply, without having to involve @keyframes: give all slides a transition property, and then toggle opacity with the fade class. That way, when the fade class changes from one slide to another, the old slide will fade out while the new one simultaneously fades in.

    You can also simplify things further by not bothering with a separate z-index for every slide. Instead of trying to literally stack the slides all on top of each other in a specific order, just worry about moving the correct one to the top of the pile, and don't worry about all the others underneath since you can't see them anyway.

    fadeSlides();
    
    
    function fadeSlides() {
      var slide = document.getElementsByClassName("fade")[0];
      var nextSlide = slide.nextElementSibling;
      
      if (nextSlide) {
        nextSlide.classList.add('fade');
      } else {
        document.getElementsByClassName('mySlides')[0].classList.add('fade');
      }
      slide.classList.remove('fade');
    
      setTimeout(fadeSlides, 3500);
    }
    .slideshow-container {
      width: 100%;
      position: relative;
    }
    
    .mySlides {
      opacity: 0;
      position: absolute;
      transition: opacity 1000ms ease;
    }
    
    .mySlides.fade {
      opacity: 1;
      z-index: 1;
    }
    <div class="slideshow-container">
      <div class="mySlides fade">
        <img src="https://i.imgur.com/h9HMwvD.png" style="width:100%">
      </div>
      <div class="mySlides">
        <img src="https://i.imgur.com/inAYNo3.png" style="width:100%">
      </div>
      <div class="mySlides">
        <img src="https://i.imgur.com/8VHulyg.png" style="width:100%">
      </div>
      <div class="mySlides">
        <img src="https://i.imgur.com/wZzx8GU.png" style="width:100%">
      </div>
      <div class="mySlides">
        <img src="https://i.imgur.com/ZPO4z3V.png" style="width:100%">
      </div>
      <div class="mySlides">
        <img src="https://i.imgur.com/yhuKaY8.png" style="width:100%">
      </div>
    </div>