A slider is an awesome functionality that can give life into an ordinary website. There are lot of scripts available today that can instantly give you this functionality and even more, but most of them are dependent to multiple libraries which may slow down your website’s performance.

If you are not a fan of using libraries like jQuery or the likes, In this tutorial I will show you how to make a pure JavaScript and CSS slider.

If you are good with CSS then this is easier for you to understand. I just use the CSS3 transition effect for the sliding animation so expect this not to work in IE 8 and older browsers that does not support CSS3. Go ahead and click the View Demo button below and view the source code first  before you continue reading the whole tutorial. Its hard to innumerate everything here so better checkout the demo.

The HTML

For the slider structure, I used a normal unordered list of images. The HTML is very straight forward and nothing fancy. I also use an unordered list for the controls.

<div id="slider" class="slider">
	<ul id="slides">
		<li class="slide"><img src="img/1.jpg"></li>
		<li class="slide"><img src="img/2.jpg"></li>
		<li class="slide"><img src="img/3.jpg"></li>
		<li class="slide"><img src="img/4.jpg"></li>
	</ul>
	<ul id="nav">
		<li><a href="#" class="nav-prev" onclick="ywtSlider.slide('back')">Prev</a></li>
		<li><a href="#" class="nav-next" onclick="ywtSlider.slide('next')">Next</a></li>
	</ul>
</div>

The CSS

CSS is the one responsible for the swiping animation effect. Using the margin property, we can form a swipe animation when the transition is applied. You can animate any properties you like as long as it can be animated. I found many developers uses opacity that can give a fadeIn/fadeout effect which also looks great for swapping images and texts.

First, I set the overflow property to hidden for the slider container. This will make our slides invisible when they are in active state (they are moved to the right). I added the width and height properties which is equal to the height and width of the slides.

#slider {
	overflow: hidden;
	width: 520px;
	height: 300px;
}

I added position property with absolute value to all the li (slide) element’s normal state to make them float inside the container. I set the left property to 100%  to move the elements to the right, then I set the negative margin-left property that is equivalent to the slide’s width to position them back to their normal position. I added the transition property so every movement of the slides with the use of margin property will result in sliding effect.

.slide {
	position: absolute;
	top: 0;
	left: 100%;
	margin-left: -520px;

	-webkit-transition: all 1s ease;
	-moz-transition: all 1s ease;
	-o-transition: all 1s ease;
	transition: all 1s ease;
}

I added an active class that will set the margin-left property to 0 which when applied to the
li 
elements will move them back to the right.

.slide.active {
	margin-left: 0;
}

To sum up the CSS and adding a little styling to the controls:

#slider {
	overflow: hidden;
	width: 520px;
	height: 300px;
}
#slides {
	list-style: none;
	margin: 0;
	padding: 0;
	position: relative;
}
.slide {
	position: absolute;
	top: 0;
	left: 100%;
	margin-left: -520px;
	z-index: 5;

	-webkit-transition: all 1s ease;
	-moz-transition: all 1s ease;
	-o-transition: all 1s ease;
	transition: all 1s ease;
}
.slide.active {
	margin-left: 0;
}
#slider #nav {
	position: absolute;
	bottom: 0;
	left: 0;
	z-index: 99999;
	list-style: none;
	margin: 0;
	padding: 10px 0;
	background: rgba(0,0,0,0.5);
	text-align: center;
	width: 100%;
}
#slider #nav li {
	display: inline-block;
	margin: 0 10px;
}
#slider #nav li:first-child {
	border-right: 1px solid #eeeeee;
	padding-right: 20px;;
}
#slider #nav li a {
	color: #ffffff;
	text-decoration: none;
}

The JavaScript

JavaScript is the one responsible for timing. First, I order the visibility of the elements. In the demo, i added z-index using for loop and apply each element’s value decremented, which means the first element will contain the highest value and decrement the next element’s value by 1.

var j = 99;
for (var i = 0; i < slide.length; i++) {
	slide[i].style.zIndex = j;
	j--;
}

I use the setInterval method as a timer which will refresh at a given interval. Each refresh, I added the active class into the next li item of the currently active element.

setInterval(function () {
    slide[itemIndex + 1].className += ' active';
}, interVal);

The element next to the last active item will serve as the active slide or the element which is visible to the slider window. Take a look at the illustration below.

slider-illus

I added a simple inspection to check if a sibling is present next to the active slide, and remove all active class if the inspection returns false to make the slider restart from the beginning. Thus result into an infinite slideshow.

if (itemIndex + 1 < slide.length - 1) {
	slide[itemIndex + 1].className += ' active';

} else {
	for (var k = 0; k < slide.length; k++) {
		slide[k].className = 'slide';
	}
}

When the previous control is fired, and the active slide is not the first element, I removed the active class to the last element with active class and all of the next siblings. If the active slide is the first element, I added the active class to the slides except the last item which will make the last item as the active slide.

var nodeList = Array.prototype.slice.call(slides.children);
var itemIndex = nodeList.indexOf(active[active.length - 1]);

if (dir == 'back') { //check and run if the direction is back
	if(itemIndex < 0) { //if the previous item does not exist (current item is the first)
		//add the active class to the slides except to the last one
		for (var l = 0; l < slide.length - 1; l++) {
			slide[l].className += ' active';
		}
	} else { //if the previous item exist
		//remove the active class starting from the current item to the last
		for (k = itemIndex; k < slide.length; k++) {
			slide[k].className = 'slide';
		}
	}
}

When the next control is fired, and the active slide is not the last element, I added the active class to the next element. If the active slide is the last element, I removed the active class to all slides.

var nodeList = Array.prototype.slice.call(slides.children);
var itemIndex = nodeList.indexOf(active[active.length - 1]);

if (dir == 'next') { //check and run if the direction is next
	if (itemIndex + 1 < slide.length - 1) { //if the next item exist
		//set the 'active' class to the next item
		slide[itemIndex + 1].className += ' active';

	} else { //if the next item does not exist (current item is the last)
		//remove the active class to all slide items
		for (var k = 0; k < slide.length; k++) {
			slide[k].className = 'slide';
		}
	}
}

To sum up the JavaScript and adding a little taste to our code:

<script type="text/javascript">
    //set the interval temporary variable
    var setIntrVal = null;
    var intrVal = 3000;

    //get the slider elements
    var slides = document.getElementById('slides'); //get the <ul id="slides">
    var slide = document.getElementsByClassName('slide'); //get the <li class="slide">
    var active = document.getElementsByClassName('active'); //get the <li class="slide active">

    //set z-index properties to the slides
    var j = 99; //initialize a higher value, change this if you need to
    for (var i = 0; i < slide.length; i++) {
        slide[i].style.zIndex = j;
        j--;
    }

    var ywtSlider = {
        init: function (newIntrVal) {
            //pass the new interval value into the intrVal variable
            if(newIntrVal) intrVal = newIntrVal;

            //start cycle on init
            ywtSlider.cycle();
        },

        cycle: function() {
            //check if cycle is already started then clear the cycle
            if(setIntrVal) clearInterval(setIntrVal); //this will clear the current interval

            //start a new cycle
            setIntrVal = setInterval(function () {
                ywtSlider.slide('next');
            }, intrVal);
        },

        slide: function (dir) {
            //get the slide index number so we can set this to the slide
            var nodeList = Array.prototype.slice.call(slides.children);
            var itemIndex = nodeList.indexOf(active[active.length - 1]);

            if (dir == 'back') { //check and run if the direction is back
                if(itemIndex < 0) { //if the previous item does not exist (current item is the first)
                    //add the active class to the slides except to the last one
                    for (var l = 0; l < slide.length - 1; l++) {
                        slide[l].className += ' active';
                    }
                } else { //if the previous item exist
                    //remove the active class starting from the current item to the last
                    for (k = itemIndex; k < slide.length; k++) {
                        slide[k].className = 'slide';
                    }
                }
            } else if (dir == 'next') { //check and run if the direction is next
                if (itemIndex + 1 < slide.length - 1) { //if the next item exist
                    //set the 'active' class to the next item
                    slide[itemIndex + 1].className += ' active';

                } else { //if the next item does not exist (current item is the last)
                    //remove the active class to all slide items
                    for (var k = 0; k < slide.length; k++) {
                        slide[k].className = 'slide';
                    }
                }
            }

            //continue the cycle
            ywtSlider.cycle();
        }
    };

    window.onload = function() {
        ywtSlider.init(5000);
    }
</script>

Click the demo below to see how our slider works, inspect the source code, study, and make an experiment to expand this idea in your own.