How to Build Simple, Easy And Universal JavaScript Slider

How to Build Simple, Easy And Universal JavaScript Slider
Reading Time: 12 minutes

Have you ever wanted to build simple universal JavaScript slider? This slider doesn’t have to be something complex. All you need is just the functionality to cycle through a number of slides. You want to go on the next slide and also the previous one. That’s it. In this quick tutorial, we will build this type of simple and universal JavaScript slider. You will build this slider in a few minutes. And, you can use it for any type of content you want. Let’s have some fun!

Table of Contents:

Quick introduction

HTML

CSS (Sass)

JavaScript

Take a look at the demo on Codepen.

The code for this tutorial is also available to download on Github.

Note: This tutorial is designed for JavaScript beginners.

Quick introduction

Before we start coding, let’s discuss what will we need. First of all, we will not need jQuery or any other JavaScript library. We will work with pure, or vanilla, JavaScript. The only thing you may need to make this tutorial work is babel compiler. The reason is that we will write all JavaScript in ES6 syntax. And, not all browsers can handle it. Therefore, we will use babel to compile ES6 into older syntax that’s supported in all browsers. This is all in the case of JavaScript.

When it comes to CSS, we will use two external resources. Fortunately, none of these resources is necessary. Therefore, you don’t have to use them if you don’t want. The first resource is font Montserrat hosted on Google Fonts. I used this font for text content of the slider. The second one is Font Awesome. I used this icon font for left and right carets. I didn’t use normalize or reset stylesheet. The last thing related to CSS is that I used autoprefixer to take care about prefixes.

HTML

The first step in this tutorial on building JavaScript Slider is creating HTML structure. Today, we will keep it very simple. We will need one div as a wrapper for the slider and its controls. This div will have class “slider-container”. Inside this div will be list (ul) with number of list items. This will be universal slider. So, some items will include text while others images. I decided to use eight items. However, feel free to use as many items as you want.

After this slider list will be another list (ul) dedicated to slider controls. This list will contain only two list items. Each of these items will contain one i element for font awesome icons. A little side note: classes with “js-*” prefix are for JavaScript. We will use these classes to bind methods.

HTML:

<!-- Slider container -->
  <div class="slider-container">
  <!-- Slider list -->
  <ul class="slider-list">
    <li class="slider-slide slider-slide-active"><img src="https://source.unsplash.com/UO02gAW3c0c/480x250" alt="" /></li>
 
    <li class="slider-slide slider-slide-hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, facilis architecto? In fuga, qui animi harum. Cupiditate sunt dolorum quisquam sint possimus maiores nesciunt eveniet ex, maxime deleniti at animi!</li>
 
    <li class="slider-slide slider-slide-hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque voluptas, laborum deleniti, eligendi qui facilis voluptate modi sunt tempore culpa, officia, error aspernatur praesentium id at quasi vitae neque explicabo.</li>
 
     <li class="slider-slide slider-slide-hidden"><img src="https://source.unsplash.com/cg78F1rKOMg/480x250" alt="" /></li>
 
     <li class="slider-slide slider-slide-hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse nulla repellat, ipsum laudantium dolorum reprehenderit vitae! Rem eius hic dignissimos voluptas minima, delectus quis natus fuga dolore suscipit laudantium.</li>
 
     <li class="slider-slide slider-slide-hidden"><img src="https://source.unsplash.com/WeYamle9fDM/480x250" alt="" /></li>
 
     <li class="slider-slide slider-slide-hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid asperiores, maxime fugiat tempora dolore, id odit magnam quae, perspiciatis porro vitae. Cumque nesciunt numquam nobis beatae voluptatum, reprehenderit quo, quaerat.</li>
 
     <li class="slider-slide slider-slide-hidden"><img src="https://source.unsplash.com/M4XgNhmLnjs/480x250" alt="" /></li>
   </ul><!-- .end Slider list -->
 
  <!-- Slider controls -->
  <div class="slider-controlls">
    <ul class="controlls-list">
      <li><a href="#" class="js-slider-left slider-control control-left"><i class="fa fa-caret-left"></i></a></li>
 
       <li><a href="#" class="js-slider-right slider-control control-right"><i class="fa fa-caret-right"></i></a></li>
    </ul>
  </div><!-- .end Slider controls -->
</div><!-- .end Slider container -->

CSS (Sass)

The second step is about styling our JavaScript slider. However, before we do that let’s take care about a couple of things. First, let’s create a simple Sass function for converting pixels to rems. If you are not familiar with any of these units, take a look at this Ultimate Guide to CSS Units.

Sass:

// Function
@function remy($value, $base: 16px) {
  @return ($value / $base) * 1rem;
}

Next, let’s create very simple keyframe for fading animation. Then, we can use this animation to make transition between slides smoother. The whole function of keyframe will be changing the opacity of the element. We will need to create only two steps, from zero to one. In other words, from completely invisible slide to visible.

Sass:

/* Animation for fading slides */
@keyframes fadeIn {
 from {
  opacity: 0;
 }

 to {
  opacity: 1;
 }
}

Now, it is time to take care about a few resets. What’s the reason for doing this? We want to avoid browser inconsistencies. The fact is that different browsers use different engines to render content of the website. As a result, our slider could look slightly different if we would view it in different browsers. However, we will keep these resets very simple. First, we will reset the font-size of html and body. Second, we will remove any padding and margin from unordered lists.

Sass:

/* Base */
html {
 font-size: 16px;
}

body {
 padding-top: 16px;// add some space above the slider
 font-family: 'Montserrat', arial, sans-serif;
 font-size: 100%;
}

ul {
 padding: 0;
 margin: 0;
}

Okay, this is what we need for setting the document and our playground for this JavaScript slider. Let’s now polish the slider-container div. We will use padding to add some inner spacing. Next, we will use left and right margin to center it. In order to make this work, let’s set max-width to, say, 480 pixels. Finally, let’s also add swagger and make it look more stylish by adding box-shadow.

Sass:

.slider-container {
 padding: remy(16px);
 margin-right: auto;
 margin-left: auto;
 max-width: remy(480px);
 box-shadow: 0 2px 8px rgba(0, 0, 0, .15), 0 4px 16px rgba(0, 0, 0, .05);
}

Next on the list is the list for our JavaScript slider. There is one problem with creating universal JavaScript slider. Individual slides might have different height. This could lead to some not so pretty results. So, for this reason, I decided to use fix height. 250 pixels will do the job. This brings one question. What if the slide has lower height than the slider? Should the content be on top with a plenty of space below it? We can solve this question by setting display to “flexbox” and aligning items to the “center”. As a result, content will be always in the middle of the slider.

Sass:

.slider-list {
 display: flex;
 align-items: center;
 height: remy(250px);
}

One thing we should also think about are images. What if some image you want to use is wider than our JavaScript slider? Then, well, it will break it. To prevent this from happening, let’s set max-width of img elements to “100%”. From now on, any image bigger than slider will automatically resize itself to it. This is the simplest fix for (relatively) responsive images.

Sass:

.slider-slide img {
 max-width: 100%;
}

Let’s get back to more important parts of our JavaScript slider, the slides. We will need to create styles for two types of slides. These are “slider-slide-hidden” and “slider-slide-active”. Again, this will be very quick and simple. Let’s take care about “slider-slide-hidden” type first. All we have to do is setting display to “none”. That’s all! In case of “slider-slide-active”, we will set the display to “block”. Then, we will create animation rule and use the keyframe we defined earlier.

Sass:

.slider-slide-hidden {
 display: none;
}

.slider-slide-active {
 display: block;
 animation: fadeIn .85s ease-in-out;
}

It is time for the last step to style our JavaScript slider. We need some styles for slider controls! Sure, you can use the “default” styles implemented by browsers vendors. However, these styles kind of suck. So, let’s create our own. But first, we have to add a few styles for the list element. We will float the controls. This will basically cause that the list will collapse. It will have no height. So, we need to implement clearfix. This is a combo of position and before and after pseudo-selectors.

After that, we will center the content of the list, the controls, by setting text-align to center. We can also add some space between the slides and controls. To do that, we will use margin-top. Now let’s style list item. We need to remove the bullets by setting list-style-type to “none”. Then, we will set float of the first list item to “left” and second to “right”. After styling list items, we need to style the links inside them.

This will require setting text-decoration to “none”. Next, use some color you like and some effect for hover. I also used transition to make the transition between colors smoother. Finally, I added some padding to make the arrows easier to click.

Sass:

.slider-controlls {
 position: relative;
 margin-top: remy(16px);
 text-align: center;

 /* Clearfix for floated items */
 &:before,
 &:after {
  content: "";
  display: table;
 }

 &:after {
  clear: both;
 }

 li {
  list-style-type: none;

  &:first-of-type {
   float: left;
  }

  &:last-of-type {
   float: right;
  }
 }

 a {
  $color: #233142;

  padding: 8px 15px;
  color: $color;
  text-decoration: none;
  transition: color .25s ease-in-out;

  &:focus,
  &:hover {
   color: lighten($color, 25%);
  }
 }
}

This is all we need for styling our JavaScript slider. Let’s now put all the pieces together.

Whole Sass code:

// Function
@function remy($value, $base: 16px) {
  @return ($value / $base) * 1rem;
}

/* Animation for fading slides */
@keyframes fadeIn {
 from {
  opacity: 0;
 }

 to {
  opacity: 1;
 }
}

/* Base */
html {
 font-size: 16px;
}

body {
 padding-top: 16px;// add some space above the slider
 font-family: 'Montserrat', arial, sans-serif;
 font-size: 100%;
}

ul {
 padding: 0;
 margin: 0;
}

.slider-container {
 padding: remy(16px);
 margin-right: auto;
 margin-left: auto;
 max-width: remy(480px);
 box-shadow: 0 2px 8px rgba(0, 0, 0, .15), 0 4px 16px rgba(0, 0, 0, .05);
}

.slider-list {
 display: flex;
 align-items: center;
 height: remy(250px);
}

.slider-slide img {
 max-width: 100%;
}

.slider-slide-hidden {
 display: none;
}

.slider-slide-active {
 display: block;
 animation: fadeIn .85s ease-in-out;
}

.slider-controlls {
 position: relative;
 margin-top: remy(16px);
 text-align: center;

 /* Clearfix for floated items */
 &:before,
 &:after {
  content: "";
  display: table;
 }

 &:after {
  clear: both;
 }

 li {
  list-style-type: none;

  &:first-of-type {
   float: left;
  }

  &:last-of-type {
   float: right;
  }
 }

 a {
  $color: #233142;

  padding: 8px 15px;
  color: $color;
  text-decoration: none;
  transition: color .25s ease-in-out;

  &:focus,
  &:hover {
   color: lighten($color, 25%);
  }
 }
}

JavaScript

The last step is creating some simple JavaScript to handle the functionality of our slider. First of all, let’s wrap the whole code for slider into self-invoking anonymous function. Then, let’s create some variables to make our work faster.

JavaScript:

(() => {
 const $slider = document.querySelector('.slider-list');

 const $sliderSlides = document.querySelectorAll('.slider-slide');

 const $sliderLeft = document.querySelector('.js-slider-left');

 const $sliderRight = document.querySelector('.js-slider-right');
})();

The first functionality of our JavaScript slider will be sliding backwards. In other words, we need to create some function to handle the scenario when user clicks on left caret. We can call this function “slideLeft”. It will require one parameter. This parameter will be e, or event. Let’s take a look at the content of this function. First, we will block the default behavior of links by using preventDefault() method. Next, let’s find current and previous slide and save both inside variables.

After that, we will use simple if statement to check if there are actually any previous slides. In other words, if we are on the first slide or not. If so, we will add “slider-slide-hidden” class to the current slide. Then, we will remove “slider-slide-active” class from it. After that, we will remove “slider-slide-hidden” class from the previous slide and add “slider-slide-active” to it. This will work if we are not on the first slide and there is some slide we can go back to.

Next, we need to create a solution for case there is no previous slide. The beginning will be the same as in the first case. Meaning, we will remove “slider-slide-active” class from current slide and add “slider-slide-hidden” class. What will come next will be different. We will use find the slider list in DOM and find its last child element. This is the last slide in our JavaScript slider. Then, we will do the same thing we did in case of previous slide. We will remove “slider-slide-hidden” class from this last child element and add “slider-slide-active”.

JavaScript:

// Create method for going on the previous slide
const slideLeft = (e) => {
 e.preventDefault();

 // Get current slide
 let $currentSlide = document.querySelector('.slider-slide-active');

 // Find the previous slide
 let $previousSlide = $currentSlide.previousElementSibling;

 if ($previousSlide !== null) {
  // If we are not on the first slide
  $currentSlide.classList.add('slider-slide-hidden');

  $currentSlide.classList.remove('slider-slide-active');

  $previousSlide.classList.remove('slider-slide-hidden');

  $previousSlide.classList.add('slider-slide-active');
 } else {
  // If we are on the first slide
  $currentSlide.classList.add('slider-slide-hidden');

  $currentSlide.classList.remove('slider-slide-active');

  $slider.lastElementChild.classList.remove('slider-slide-hidden');

  $slider.lastElementChild.classList.add('slider-slide-active');
 }
};

This is the code we need to make sliding backward work. The method for the sliding forward, called “slideRight”, will be very similar to “slideLeft”. The only difference is that will not use variable for previous slide, but for the next slide. Also, in case there is no next slide, we will look for first element child of the slider list instead of last.

JavaScript:

// Create method for going on the next slide
const slideRight = (e) => {
 e.preventDefault();

 // Get current slide
 let $currentSlide = document.querySelector('.slider-slide-active');

 // Find the next slide
 let $nextSlide = $currentSlide.nextElementSibling;

 if ($nextSlide !== null) {
  // If we are not on the last slide
  $currentSlide.classList.add('slider-slide-hidden');

  $currentSlide.classList.remove('slider-slide-active');

  $nextSlide.classList.remove('slider-slide-hidden');

  $nextSlide.classList.add('slider-slide-active');
 } else {
  // If we are on the last slide
  $currentSlide.classList.add('slider-slide-hidden');

  $currentSlide.classList.remove('slider-slide-active');

  $slider.firstElementChild.classList.remove('slider-slide-hidden');

  $slider.firstElementChild.classList.add('slider-slide-active');
 }
};

Finally, we need to bind these two sliding functions to slider buttons, arrows. To do that, we will need to use addEventListener() method. This method takes three parameters. The first one is the event we want to listen to. This will be “click” event. The second one is the function we want execute when something triggers the event. Finally, the third parameter is for specifying whether you want to initiate capture of the event. Very good explanation of this parameter is on Stackoverflow.

JavaScript:

// Create eventListener for click on the left arrow
$sliderLeft.addEventListener('click', slideLeft, false);

// Create eventListener for click on the right arrow
$sliderRight.addEventListener('click', slideRight, false);

Let’s make this JavaScript slider better! Why don’t we allow users to control our slider with arrow keys? Don’t worry, it will be relatively quick. First, we will need to create two custom events. One event will be for sliding to the left and second for sliding to the right. Then, we will bind these custom events to bind event listeners listening to the events with the same name. The function to be executed (second parameter) will be our sliding functions.

The last step is to make all this work is about adding one more event listener. This time, it will be for “keydown” event. We will add this event to the document object. When this event happens we will detect the keyCode of the key. Then, we will use if statement to trigger either event for sliding to the left or sliding to the right.

JavaScript:

// Create new custom event for sliding to the left
const slideLeftEvent = new Event('slideLeft');

// Create new custom event for sliding to the right
const slideRightEvent = new Event('slideRight');

// Create eventListener for pressing the left key
$sliderLeft.addEventListener('slideLeft', slideLeft, false);

// Create eventListener for pressing the right key
$sliderRight.addEventListener('slideRight', slideRight, false);

// Listen to keydown event
document.addEventListener('keydown', (e) => {
 e = e || window.event;

 if (e.keyCode === 37) {
  // If pressed key was left arrow
  $sliderLeft.dispatchEvent(slideLeftEvent);
 } else if (e.keyCode === 39) {
  // If pressed key was right arrow
  $sliderRight.dispatchEvent(slideRightEvent);
 }
}, false);

Again, let’s put all the pieces we created in the steps above together.

Whole JavaScript code:

(() => {
 const $slider = document.querySelector('.slider-list');

 const $sliderSlides = document.querySelectorAll('.slider-slide');

 const $sliderLeft = document.querySelector('.js-slider-left');

 const $sliderRight = document.querySelector('.js-slider-right');

 // Create method for going on the previous slide
 const slideLeft = (e) => {
  e.preventDefault();

  // Get current slide
  let $currentSlide = document.querySelector('.slider-slide-active');

  // Find the previous slide
  let $previousSlide = $currentSlide.previousElementSibling;

  if ($previousSlide !== null) {
   // If we are not on the first slide
   $currentSlide.classList.add('slider-slide-hidden');

   $currentSlide.classList.remove('slider-slide-active');

   $previousSlide.classList.remove('slider-slide-hidden');

   $previousSlide.classList.add('slider-slide-active');
  } else {
   // If we are on the first slide
   $currentSlide.classList.add('slider-slide-hidden');

   $currentSlide.classList.remove('slider-slide-active');

   $slider.lastElementChild.classList.remove('slider-slide-hidden');

   $slider.lastElementChild.classList.add('slider-slide-active');
  }
 };

 // Create method for going on the next slide
 const slideRight = (e) => {
  e.preventDefault();

  // Get current slide
  let $currentSlide = document.querySelector('.slider-slide-active');

  // Find the next slide
  let $nextSlide = $currentSlide.nextElementSibling;

  if ($nextSlide !== null) {
   // If we are not on the last slide
   $currentSlide.classList.add('slider-slide-hidden');

   $currentSlide.classList.remove('slider-slide-active');

   $nextSlide.classList.remove('slider-slide-hidden');

   $nextSlide.classList.add('slider-slide-active');
  } else {
   // If we are on the last slide
   $currentSlide.classList.add('slider-slide-hidden');

   $currentSlide.classList.remove('slider-slide-active');

   $slider.firstElementChild.classList.remove('slider-slide-hidden');

   $slider.firstElementChild.classList.add('slider-slide-active');
  }
 };

 // Create new custom event for sliding to the left
 const slideLeftEvent = new Event('slideLeft');

 // Create new custom event for sliding to the right
 const slideRightEvent = new Event('slideRight');

 // Create eventListener for click on the left arrow
 $sliderLeft.addEventListener('click', slideLeft, false);

 // Create eventListener for click on the right arrow
 $sliderRight.addEventListener('click', slideRight, false);

 // Create eventListener for pressing the left key
 $sliderLeft.addEventListener('slideLeft', slideLeft, false);

 // Create eventListener for pressing the right key
 $sliderRight.addEventListener('slideRight', slideRight, false);

 // Listen for keydown event
 document.addEventListener('keydown', (e) => {
  e = e || window.event;

  if (e.keyCode === 37) {
   // If pressed key was left arrow
   $sliderLeft.dispatchEvent(slideLeftEvent);
  } else if (e.keyCode === 39) {
   // If pressed key was right arrow
   $sliderRight.dispatchEvent(slideRightEvent);
  }
 }, false);
})();

Closing thoughts on building simple JavaScript Slider

Hey, congratulations! You’ve just built your own simple JavaScript slider! It wasn’t that hard, right? In a fact, I think that this tutorial was almost too easy for you. It wasn’t challenging enough. So, let’s do something to change this. If you want to raise the bar, one option is implementing new functionality. For example, you can add function that will allow users enable automatic sliding. Then, they will not have to click on anything or press any keys.

The question is, do you have the courage to accept this challenge? Will you take up the gauntlet? I want to encourage you to do it. We discussed this in the article about how to learn JavaScript. Pushing yourself beyond your limits is great for improving your skills and learning faster. So, go ahead and create your own solution for this challenge. And, make sure to share it!

Thank you very much for your time.

Master the skills of design, development and business. Learn the skills you need to become tech and design entrepreneur! Subscribe to my blog.

Leave a Reply