Gallery
Introduction
In this tutorial, you'll learn how to control the slider by basic APIs with creating the following gallery. Thumbnails are clickable to navigate the slider and respond to the slider changes.
HTML and CSS
First, we need to write HTML of the slider and thumbnails:
<
div
id
=
"main-slider"
class
=
"splide"
>
<
div
class
=
"splide__track"
>
<
ul
class
=
"splide__list"
>
<
li
class
=
"splide__slide"
>
<
img
src
=
"image1.jpg"
/
>
<
/
li
>
<
li
class
=
"splide__slide"
>
<
img
src
=
"image2.jpg"
/
>
<
/
li
>
<
li
class
=
"splide__slide"
>
<
img
src
=
"image3.jpg"
/
>
<
/
li
>
<
li
class
=
"splide__slide"
>
<
img
src
=
"image4.jpg"
/
>
<
/
li
>
<
/
ul
>
<
/
div
>
<
/
div
>
<
ul
id
=
"thumbnails"
class
=
"thumbnails"
>
<
li
class
=
"thumbnail"
>
<
img
src
=
"thumbnail1.jpg"
/
>
<
/
li
>
<
li
class
=
"thumbnail"
>
<
img
src
=
"thumbnail2.jpg"
/
>
<
/
li
>
<
li
class
=
"thumbnail"
>
<
img
src
=
"thumbnail3.jpg"
/
>
<
/
li
>
<
li
class
=
"thumbnail"
>
<
img
src
=
"thumbnail4.jpg"
/
>
<
/
li
>
<
/
ul
>
HTML
<div id="main-slider" class="splide"> <div class="splide__track"> <ul class="splide__list"> <li class="splide__slide"> <img src="image1.jpg" /> </li> <li class="splide__slide"> <img src="image2.jpg" /> </li> <li class="splide__slide"> <img src="image3.jpg" /> </li> <li class="splide__slide"> <img src="image4.jpg" /> </li> </ul> </div> </div> <ul id="thumbnails" class="thumbnails"> <li class="thumbnail"> <img src="thumbnail1.jpg" /> </li> <li class="thumbnail"> <img src="thumbnail2.jpg" /> </li> <li class="thumbnail"> <img src="thumbnail3.jpg" /> </li> <li class="thumbnail"> <img src="thumbnail4.jpg" /> </li> </ul>
Then, style thumbnails as you like. This example uses this CSS:
.thumbnails
{
display
:
flex
;
margin
:
1
rem
auto
0
;
padding
:
0
;
justify-content
:
center
;
}
.thumbnail
{
width
:
70
px
;
height
:
70
px
;
overflow
:
hidden
;
list-style
:
none
;
margin
:
0
0.2
rem
;
cursor
:
pointer
;
}
.thumbnail
img
{
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; }
Slider
Next, initialize the main slider. This example disables indicator dots because the slider will have the thumbnail control:
var
splide
=
new
Splide
(
'#main-slider'
,
{
pagination
:
false
,
}
)
;
splide
.
mount
(
)
;
JavaScript
var splide = new Splide( '#main-slider', { 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:
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 slider
}
)
;
}
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 slider } ); }
You can move the slider via the Splide#go()
method:
var
splide
=
new
Splide
(
...
)
;
...
function
initThumbnail
(
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 slider 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 slider moves:
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
;
}
}
)
;
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 remove the class when it changes.
By using the is-active
class, we can clarify the selected thumbnail like this:
.thumbnail
{
...
opacity
:
0.3
;
}
.thumbnail.is-active
{
opacity
:
1
;
}
CSS
.thumbnail { ... opacity: 0.3; } .thumbnail.is-active { opacity: 1; }
As we add the class when the slider moves, no slide is active initially. So, we also need to update the class when the slider is initialized:
splide
.
on
(
'mounted move'
,
function
(
)
{
...
}
)
;
JavaScript
splide.on( 'mounted move', function () { ... } );
We're done! 🎉 Here is the whole code of this tutorial:
12345678910111213141516171819202122232425262728293031var
splide
=
new
Splide
(
'#main-slider'
,
{
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
(
)
;
JavaScript
var splide = new Splide( '#main-slider', { 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 the accessibility by implementing these things:
- Assign
tabindex="0"
to thumbnails for keyboard users - Add
aria-label
to tell what happens when the user selects each thumbnail - Add
aria-current
to the active thumbnail - Link thumbnails to the slider by
aria-controls
for some assistive technologies