09. The Slideshow

Include Morrigan’s prebuilt scripts

Mentor Morrigan

Your task

CSS
/* Container around the slideshow */
.slider-container {
   max-width: 700px;
   position: relative;
   overflow: hidden;
   border-radius: var(--border-large);
   height: 600px;
}

/* Each slide is stacked on top of each other */
.slide {
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   /* Initially hidden */
   opacity: 0;
   transition: opacity 1s ease;
   /* Fade-in over 1 second */
}

/* The active slide is displayed */
.slide.active {
   opacity: 1;
   z-index: 1;
   /* Brings the active slide to the front */
}

/* Image within the slide fills the entire space */
.slide img {
   width: 100%;
   height: 100%;
   object-fit: cover;
   /* Adjusts the image to fit the container, cropping if necessary */
   display: block;
}

/* Text overlay at the bottom of the image */
.slide-text {
   position: absolute;
   bottom: 0;
   left: 0;
   right: 0;
   color: var(--light);
   padding: var(--spacing-base);
   text-align: center;
   text-shadow: var(--shadow-dark);
   font-size: var(--font-size-base);
   background-color: var(--transparent-dark)
}

.slide-text h3 {
   font-family: var(--accent-font);
   font-weight: var(--bold);
   font-variant: small-caps;
   letter-spacing: 1px;
   font-size: var(--font-size-large)
}

@media (width<768px) {
   .slide-text h3 {
      font-size: var(--font-size-title);
   }
}

/* Previous and next buttons */
.prev,
.next {
   cursor: pointer;
   position: absolute;
   top: 50%;
   transform: translateY(-50%);
   background-color: var(--transparent-dark);
   color: #fff;
   border: none;
   font-size: 2rem;
   padding: 10px;
   z-index: 10;
   transition: var(--transition);
   /* Above the slides */
}

.prev {
   left: 0;
}

.next {
   right: 0;
}

.prev:hover,
.next:hover {
   background-color: var(--transparent-dark);
}
JavaScript
(function () {
    // Slideshow
    // Collect all slides
    const slides = document.querySelectorAll('.slide');
    let currentIndex = 0;
    const totalSlides = slides.length;

    // Buttons
    const prevBtn = document.getElementById('prevBtn');
    const nextBtn = document.getElementById('nextBtn');

    // Automatic switch (in ms)
    const intervalTime = 5000; // 5 seconds
    let slideInterval;

    // Shows the slide at the given index
    function showSlide(index) {
        // Remove active from all
        slides.forEach(slide => slide.classList.remove('active'));
        // Add active to the desired slide
        slides[index].classList.add('active');
    }

    // Next
    function nextSlide() {
        currentIndex++;
        if (currentIndex >= totalSlides) {
            currentIndex = 0;
        }
        showSlide(currentIndex);
    }

    // Previous
    function prevSlide() {
        currentIndex--;
        if (currentIndex < 0) {
            currentIndex = totalSlides - 1;
        }
        showSlide(currentIndex);
    }

    // Manual navigation
    nextBtn.addEventListener('click', () => {
        nextSlide();
        resetInterval(); // Restart interval
    });

    prevBtn.addEventListener('click', () => {
        prevSlide();
        resetInterval(); // Restart interval
    });

    // Automatic start
    function startInterval() {
        slideInterval = setInterval(nextSlide, intervalTime);
    }

    // Restart interval on click
    function resetInterval() {
        clearInterval(slideInterval);
        startInterval();
    }

    // Show initially + start interval
    showSlide(currentIndex);
    startInterval();
})();

Link the HTML, CSS, and JavaScript correctly.
In the live editor, you must insert the HTML first, then the CSS, and JavaScript comes last – otherwise, it won’t work.

The working slideshow is shown in the cheat sheet.

Hiram crosses his arms, watching you with a scrutinizing gaze. “And remember: it’s not enough that it works – it has to fit. Use the right images and texts.
We want this to feel seamless – not like a patchwork quilt.”

Solve the task here in the console [–> Open in a new tab]

HTML
<!-- HTML -->
<!-- Slider -->
<div class="slider-container">
     <!-- Slide 1 -->
     <div class="slide active">
          <!-- Adjust the path if necessary -->
          <img src="img/world/sunnyside-fields.jpg" alt="Sunnyside Fields">
          <div class="slide-text">
               <h3>Sunnyside Fields</h3>
               <p>Sunny fields and gently blooming hills</p>
          </div>
     </div>

     <!-- Slide 2 -->
     <div class="slide">
          <img src="img/world/greenwood-hollow.jpg" alt="Image 2">
          <div class="slide-text">
               <h3>Greenwood Hollow</h3>
               <p>A dense, mystical forest full of secrets</p>
          </div>
     </div>

     <!-- Slide 3 -->
     <div class="slide">
          <img src="img/world/skyterranova.jpg" alt="Image 3">
          <div class="slide-text">
               <h3>Skyterranova</h3>
               <p>Fragments of another world, floating in the mist</p>
          </div>
     </div>

     <!-- Slide 4 -->
     <div class="slide">
          <img src="img/world/vcoraths-labyrinth.jpg" alt="Image 4">
          <div class="slide-text">
               <h3>Vorath's Labyrinth</h3>
               <p>Twisting paths and walls of shadow</p>
          </div>
     </div>

     <!-- Slide 5 -->
     <div class="slide">
          <img src="img/world/shadow-fortress.jpg" alt="Image 5">
          <div class="slide-text">
               <h3>Shadow Fortress</h3>
               <p>Dark walls pierced by whispering shadows</p>
          </div>
     </div>

     <!-- Slide 6 -->
     <div class="slide">
          <img src="img/world/ironspire.jpg" alt="Image 6">
          <div class="slide-text">
               <h3>Ironspire</h3>
               <p>A city of steel, cold and menacing</p>
          </div>
     </div>

     <!-- Buttons -->
     <button class="prev" id="prevBtn"></button>
     <button class="next" id="nextBtn"></button>
</div>
Scroll to Top