Gallery
Introduction
In this tutorial, you'll learn how to control a carousel by basic APIs with creating the following gallery. When the main carousel moves, the active thumbnail will change. Also, thumbnails are clickable to navigate the main carousel.
HTML and CSS
First, let's write markup to create a carousel and thumbnails.
Make sure to describe your images by alt:
<sectionid="main-carousel"class="splide"aria-label="My Awesome Gallery"><divclass="splide__track"><ulclass="splide__list"><liclass="splide__slide"><imgsrc="image1.jpg"alt=""></li><liclass="splide__slide"><imgsrc="image2.jpg"alt=""></li><liclass="splide__slide"><imgsrc="image3.jpg"alt=""></li><liclass="splide__slide"><imgsrc="image4.jpg"alt=""></li></ul></div></section><ulid="thumbnails"class="thumbnails"><liclass="thumbnail"><imgsrc="thumbnail1.jpg"alt=""></li><liclass="thumbnail"><imgsrc="thumbnail2.jpg"alt=""></li><liclass="thumbnail"><imgsrc="thumbnail3.jpg"alt=""></li><liclass="thumbnail"><imgsrc="thumbnail4.jpg"alt=""></li></ul>HTML
<section id="main-carousel" class="splide" aria-label="My Awesome Gallery">
<div class="splide__track">
<ul class="splide__list">
<li class="splide__slide">
<img src="image1.jpg" alt="">
</li>
<li class="splide__slide">
<img src="image2.jpg" alt="">
</li>
<li class="splide__slide">
<img src="image3.jpg" alt="">
</li>
<li class="splide__slide">
<img src="image4.jpg" alt="">
</li>
</ul>
</div>
</section>
<ul id="thumbnails" class="thumbnails">
<li class="thumbnail">
<img src="thumbnail1.jpg" alt="">
</li>
<li class="thumbnail">
<img src="thumbnail2.jpg" alt="">
</li>
<li class="thumbnail">
<img src="thumbnail3.jpg" alt="">
</li>
<li class="thumbnail">
<img src="thumbnail4.jpg" alt="">
</li>
</ul>
Then, style thumbnails as you like. This example uses this CSS:
.thumbnails{display:flex;margin:1remauto0;padding:0;justify-content:center;}.thumbnail{width:70px;height:70px;overflow:hidden;list-style:none;margin:00.2rem;cursor:pointer;}.thumbnailimg{width:100%;height:auto;}CSS
.thumbnails {
display: flex;
margin: 1rem auto 0;
padding: 0;
justify-content: center;
}
.thumbnail {
width: 70px;
height: 70px;
overflow: hidden;
list-style: none;
margin: 0 0.2rem;
cursor: pointer;
}
.thumbnail img {
width: 100%;
height: auto;
}
Main Carousel
Next, apply Splide to the main carousel. This example disables pagination because the carousel will have the thumbnail control:
varsplide=newSplide('#main-carousel',{pagination:false,});splide.mount();JavaScript
var splide = new Splide( '#main-carousel', {
pagination: false,
} );
splide.mount();
Thumbnails
Okay, the most important part is coming 💪
To make thumbnails clickable, we need to listen to their click events:
// Collects LI elements:varthumbnails=document.getElementsByClassName('thumbnail');for(vari=0;i<thumbnails.length;i++){initThumbnail(thumbnails[i],i);}// The function to initialize each thumbnail.functioninitThumbnail(thumbnail,index){thumbnail.addEventListener('click',function(){// move the carousel});}JavaScript
// Collects LI elements:
var thumbnails = document.getElementsByClassName( 'thumbnail' );
for ( var i = 0; i < thumbnails.length; i++ ) {
initThumbnail( thumbnails[ i ], i );
}
// The function to initialize each thumbnail.
function initThumbnail( thumbnail, index ) {
thumbnail.addEventListener( 'click', function () {
// move the carousel
} );
}
When the user clicks thumbnail, the main carousel should move to the corresponded slide.
You can move the carousel via Splide#go() that can take a slide index:
varsplide=newSplide(...);...functioninitThumbnail(thumbnail,index){thumbnail.addEventListener('click',function(){splide.go(index);});}JavaScript
var splide = new Splide( ... );
...
function initThumbnail( thumbnail, index ) {
thumbnail.addEventListener( 'click', function () {
splide.go( index );
} );
}
Now we can navigate the carousel by clicking thumbnails, but the user won't be sure which thumbnail is currently selected.
To emphasize it by CSS, let's add the is-active class to the active thumbnail.
You can toggle the class by listening to 'move' event triggered every time when the carousel moves:
varthumbnails=document.getElementsByClassName('thumbnail');varcurrent;// Keeps the current thumbnail...splide.on('move',function(){if(current){current.classList.remove('is-active');}// Splide#index returns the latest slide index:varthumbnail=thumbnails[splide.index];if(thumbnail){thumbnail.classList.add('is-active');current=thumbnail;}});JavaScript
var thumbnails = document.getElementsByClassName( 'thumbnail' );
var current; // Keeps the current thumbnail
...
splide.on( 'move', function () {
if ( current ) {
current.classList.remove( 'is-active' );
}
// Splide#index returns the latest slide index:
var thumbnail = thumbnails[ splide.index ];
if ( thumbnail ) {
thumbnail.classList.add( 'is-active' );
current = thumbnail;
}
} );
The current variable holds the current thumbnail element so that we can remove is-active when it changes.
By using the is-active class, we can clarify the selected thumbnail like so:
.thumbnail{...opacity:0.3;}.thumbnail.is-active{opacity:1;}CSS
.thumbnail {
...
opacity: 0.3;
}
.thumbnail.is-active {
opacity: 1;
}
That's better — but as we add the class when the carousel moves, no slide is active initially.
We can fix it by the mounted event fired right after the carousel is initialized:
splide.on('mounted move',function(){...});JavaScript
splide.on( 'mounted move', function () {
...
} );
We're done! 🎉 Here is the whole code of this tutorial:
12345678910111213141516171819202122232425262728293031varsplide=newSplide('#main-carousel',{pagination:false,});varthumbnails=document.getElementsByClassName('thumbnail');varcurrent;for(vari=0;i<thumbnails.length;i++){initThumbnail(thumbnails[i],i);}functioninitThumbnail(thumbnail,index){thumbnail.addEventListener('click',function(){splide.go(index);});}splide.on('mounted move',function(){varthumbnail=thumbnails[splide.index];if(thumbnail){if(current){current.classList.remove('is-active');}thumbnail.classList.add('is-active');current=thumbnail;}});splide.mount();JavaScript
var splide = new Splide( '#main-carousel', {
pagination: false,
} );
var thumbnails = document.getElementsByClassName( 'thumbnail' );
var current;
for ( var i = 0; i < thumbnails.length; i++ ) {
initThumbnail( thumbnails[ i ], i );
}
function initThumbnail( thumbnail, index ) {
thumbnail.addEventListener( 'click', function () {
splide.go( index );
} );
}
splide.on( 'mounted move', function () {
var thumbnail = thumbnails[ splide.index ];
if ( thumbnail ) {
if ( current ) {
current.classList.remove( 'is-active' );
}
thumbnail.classList.add( 'is-active' );
current = thumbnail;
}
} );
splide.mount();
This sample code is available in CodeSandbox too.
This gallery is not compatible with the destroy option because Splide discards all handlers on destruction. You need to create an extension to make it work with the option.
Tips
I highly recommend improving accessibility by implementing these things:
- Assign
tabindex="0"to thumbnails for keyboard users - Add
aria-labelto tell what happens when the user clicks each thumbnail (aria-label="Go to slide 1"). - Add
aria-currentto the active thumbnail - Link thumbnails to each slide by
aria-controls



