How to create a slider using only JavaScript and CSS, without including other libraries
My example below is going to show you how to create the simple slider from images. You can use a solution like this for any group of images you have, you would need a wrapper element for the images and for the navigation elements.

Simplified Markup
When adding the image widget in a sidebar, the output would be more complicated in terms of markup, but for this simple demo, I will simplify the markup completely, let’s say like this, also including the two elements that are going to be used for navigation:
<div id="my-custom-slider-demo" class="sidebar-slider">
<a id="sidebar-slider-prev" onclick="customNavToPrevSlide()"> ❮ </a>
<a id="sidebar-slider-next" onclick="customNavToNextSlide()"> ❯ </a>
<div id="demo-slide1" class="widget_media_image">
<b class="widget-title">Slide 1 Title</b>
<a href="#"><img width="700" height="200" src="photo1.jpg"></a>
</div>
<div id="demo-slide2" class="widget_media_image">
<b class="widget-title">Slide 2 Title</b>
<a href="#"><img width="700" height="200" src="photo2.jpg"></a>
</div>
<div id="demo-slide3" class="widget_media_image">
<b class="widget-title">Slide 3 Title</b>
<a href="#"><img width="700" height="200" src="photo3.jpg"></a>
</div>
</div>
In this markup, the slide is any element that contains an image, and that is marked with the class widget_media_image
. Whatever is inside the “slide” will need to transition between the two states: active/inactive. By default, I would consider using only one class to specify which slide is active, by adding the active
class to that element, and whatever does not have that class would be handled as “inactive” in the custom CSS.
The CSS Code
I would first style the elements so that these are all displayed in the same position, and the images stretch to the maximum width of the wrapper. The slide title will be placed over the images, and the navigation arrows will only display when you move the mouse over the slider so that these do not cover too much space or attract attention, the main focus would be the image. By default, the first element that contains the image would be visible.
I would also put in place a simple CSS:
#my-custom-slider-demo {
display: block;
overflow: hidden;
position: relative;
}
#my-custom-slider-demo #sidebar-slider-prev,
#my-custom-slider-demo #sidebar-slider-next {
background-color: rgba(0,0,0,0.5);
color: #FFF;
cursor: pointer;
display: inline-block;
font-size: 32px;
height: 48px;
line-height: 42px;
opacity: 0;
padding: 0;
position: absolute;
text-align: center;
top: calc(50% - 24px);
transition: 0.2s all;
width: 48px;
z-index: 5;
}
#my-custom-slider-demo #sidebar-slider-next {
right: 0;
}
#my-custom-slider-demo:hover #sidebar-slider-prev,
#my-custom-slider-demo:hover #sidebar-slider-next{
opacity: 1;
}
#my-custom-slider-demo .widget_media_image {
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top:0;
transition: 0.8s all;
z-index: 0;
width: 100%;
}
#my-custom-slider-demo .widget_media_image:first-of-type,
#my-custom-slider-demo .widget_media_image.active {
opacity: 1;
z-index: 1;
}
#my-custom-slider-demo .widget_media_image img {
height: auto;
width: 100%;
}
#my-custom-slider-demo .widget_media_image b {
background-color: rgba(0,0,0,0.5);
bottom: 0;
color: #FFF;
display: inline-block;
font-size: 14px;
left: 0;
padding: 10px 20px;
position: absolute;
text-transform: uppercase;
}
@media all and (max-width: 600px) {
#my-custom-slider-demo .widget_media_image b {
display: none;
}
}
The JavaScript Code
Additionally, I would need to check if there are any elements that contain the images and look like my “slides”, by looking for the class widget_media_image
.
By default, the first slide would be active, and after 5 seconds (in the script this appears as the second parameter for setInterval
inside the customSliderStart
function, but you can change it to what you need) the next slide will become active, and so on. However, when I click the navigation arrows, I have to make sure that another transition is not ready to fire, so I have to clear the interval first, so the slider will not glitch.
The JavaScript code is:
let currentSlide = 0, theSlides = document.getElementsByClassName('widget_media_image'), customSliderTimer, next, prev, theWrapper = document.getElementById('my-custom-slider-demo');
function customNavToNextSlide() {
next = ( currentSlide < theSlides.length - 1 ) ? currentSlide + 1 : 0;
customSetCurrentSlide(next);
}
function customNavToPrevSlide() {
prev = ( currentSlide > 0 ) ? currentSlide - 1 : theSlides.length - 1;
customSetCurrentSlide(prev);
}
function customSetCurrentSlide(to) {
clearInterval(customSliderTimer);
for (let i = 0; i < theSlides.length; i ++) {
if ( currentSlide == i ) {
theSlides[currentSlide].classList.remove('active');
}
if ( next == i ) {
theSlides[to].classList.add('active');
}
}
currentSlide = to;
customSliderStart();
}
function customSliderStart() {
customSliderTimer = setInterval(function() {
customNavToNextSlide();
}, 5000);
}
function customSliderInit() {
let height = theSlides[0].getElementsByTagName('img')[0].height;
theWrapper.style.height = height + 'px';
for (let i = 0; i < theSlides.length; i ++) {
theSlides[i].style.height = height + 'px';
}
}
if (typeof theSlides !== 'undefined') {
window.addEventListener('resize', customSliderInit);
customSliderInit();
if ( theSlides.length > 1 ) {
customSliderStart();
}
}