09. The Slideshow
Include Morrigan’s prebuilt scripts
Mentor Morrigan

Morrigan tosses you a few scrolls that smell faintly of scorched parchment.
“Here. This is the script for the slideshow. Link it with the matching CSS and place the HTML into the first box.”
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>