Finally, after going through the core concepts in JavaScript, as well as how the language works in the browser environment, you are ready to create your first real project using HTML, CSS, and JavaScript.
In this lesson, we are going to walk through how to build an image slider. We will demonstrate two different approaches, one opacity
based and the other transform
based.
Creating HTML
Let's first start with the HTML code:
1<div class="slider">
2 <div class="slide">
3 <img src="/media/course/javascript/1.jpg" alt="demo image" />
4 </div>
5 <div class="slide">
6 <img src="/media/course/javascript/2.jpg" alt="demo image" />
7 </div>
8 . . .
9 <a class="prev" onclick="prevSlide()"><</a>
10 <a class="next" onclick="nextSlide()">></a>
11</div>
.slider
acts as the container for the entire image slider.- Individual slide is enclosed in a
.slide
container along with the image. - The slider navigation is controlled by two links,
.prev
and.next
.
We also have the onclick
event listener set up for the navigation links, and when they are clicked, the corresponding JavaScript functions will be activated.
Of course, you could use the addEventListener()
function. But because this example doesn't require callbacks that are too complex, we'll use the HTML attribute method here.
Adding styles
For easier styling of elements, it is recommended to remove the default paddings and margins of all elements, and set box-sizing
to border-box
. This allows the elements to be sized based on their border-box
dimensions rather than content-box
.
1* {
2 padding: 0px;
3 margin: 0px;
4 box-sizing: border-box;
5}
And then add the styles for the .slider
.
1.slider {
2 width: 500px;
3 height: 300px;
4 margin: auto;
5 overflow: hidden;
6 transform: translateY(50%);
7}
As well as individual .slide
.
1.slide {
2 position: absolute;
3 top: 50%;
4 transform: translateY(-50%);
5}
6
7img {
8 width: 100%;
9 height: auto;
10}
Line 2 to 4 centers the .slide
inside the .slider
container.
Lastly, we'll also place the navigation links on the left and right side of the .slider
container.
1.prev,
2.next {
3 cursor: pointer;
4 background-color: #333;
5 color: #fff;
6 padding: 10px 20px;
7 position: absolute;
8 top: 50%;
9 transform: translateY(-50%);
10 text-decoration: none;
11}
12
13.prev {
14 left: 0;
15}
16
17.next {
18 right: 0;
19}
Adding JavaScript code
Now, let's take a closer look at the styles for each individual .slide
.
1.slide {
2 position: absolute;
3 top: 50%;
4 transform: translateY(-50%);
5}
By using the absolute
position, we placed all individual .slide
s in one location, stacked on top of each other. You can verify that using the developer tools in your browser.
To reveal the image underneath, all you need to do is setting the opacity
of the current slide to 100
(completely visible), while setting the opacity
of all other slides to 0
(completely invisible).
And to achieve the slideshow effect, you can set up your JavaScript code so that whenever a navigation link is clicked, the "current slide" adjusts accordingly.
We'll start by setting the opacity
of all slides to 0
by default.
1.slide {
2 position: absolute;
3 top: 50%;
4 transform: translateY(-50%);
5
6 opacity: 0;
7 transition: opacity 1s ease;
8}
And then add the following JavaScript code.
1const slides = document.querySelectorAll(".slide");
2let currentSlide = 0;
3
4function showSlide(index) {
5 slides.forEach((slide, i) => {
6 if (i === index) {
7 slide.style.opacity = 100;
8 } else {
9 slide.style.opacity = 0;
10 }
11 });
12}
13
14function nextSlide() {
15 currentSlide = (currentSlide + 1) % slides.length;
16 showSlide(currentSlide);
17}
18
19function prevSlide() {
20 currentSlide = (currentSlide - 1 + slides.length) % slides.length;
21 showSlide(currentSlide);
22}
23
24showSlide(currentSlide);
Line 1, the querySelectorAll()
method selects all elements under the class .slide
, and the result will be placed in an array-like collection and assigned to the variable slides
.
Line 2, we initiate the variable currentSlide
to be 0
, which points to the first slide in the image slider.
Now, let's take a look at the nextSlide()
function.
1function nextSlide() {
2 currentSlide = (currentSlide + 1) % slides.length;
3 showSlide(currentSlide);
4}
In this case, slides.length
gives the total number of slides in the slider, and when this function is executed (by clicking the .next
link), the currentSlide
will be adjusted accordingly.
For example, when the function is executed the first time, assuming there are five slides in total:
1currentSlide = (0 + 1) % 5 = 1
But when it is executed the fifth time, currentSlide
will reset back to 0
.
1currentSlide = (4 + 1) % 5 = 0
The prevSlide()
function works similarly.
1function prevSlide() {
2 currentSlide = (currentSlide - 1 + slides.length) % slides.length;
3 showSlide(currentSlide);
4}
When currentSlide
is 4
, which points to the fifth slide:
1currentSlide = (4 - 1 + 5) % 5 = 3
When currentSlide
is 0
, which points to the first slide:
1currentSlide = (0 - 1 + 5) % 5 = 4
The currentSlide
variable will then be passed to the showSlide()
function as the index
.
1function showSlide(index) {
2 slides.forEach((slide, i) => {
3 if (i === index) {
4 slide.style.opacity = 100;
5 } else {
6 slide.style.opacity = 0;
7 }
8 });
9}
This function iterates over all slides stored in slides
, and if the iteration index (variable i
) matches the currentSlide
index (variable index
), then that slide will have its opacity
set to 100
. If not, its opacity
will be 0
.
This will be the final result ⬇️
Sliding with CSS transform
We called it an image slider, but as you can see from the final result, there is not much sliding because the transition is based on opacity
.
How can we adjust our code so that when the navigation link is clicked, the image actually slides over to the next?
There are two alterations you must make.
First, the .slide
s must be arranged horizontally behind the .slider
container, instead of stacked on top of each other. You can think of the .slider
container as a window. Every time a link is clicked, the .slide
s get shifted left or right to reveal the next or the previous image.
1.slider {
2 width: 500px;
3 height: 300px;
4 margin: auto;
5 overflow: hidden;
6 transform: translateY(50%);
7
8 display: flex;
9 align-items: center;
10}
11
12.slide {
13 flex: 0 0 100%;
14 transition: transform 1s ease;
15}
We are using a flexbox layout to achieve this effect. flex: 0 0 100%
sets the width of each .slide
to be 100% of the .slider
.
Next, adjust the showSlide()
function.
1function showSlide(index) {
2 slides.forEach((slide, i) => {
3 const slideWidth = slide.clientWidth;
4 slide.style.transform = `translateX(-${index * slideWidth}px)`;
5 });
6}
Again, assuming there are five slides in total, and each slide is 500px
wide. When index is 3
, index * slideWidth
would be 1500
, and translateX(-1500px)
will shift all .slide
s to the left by 1500
pixels, revealing the fourth image.