A simple DIY responsive image slideshow made with HTML5, CSS3, and JavaScript

“It takes half your life before you discover life is a do-it-yourself project.” ― Napoleon Hill

IMPORTANT: I’ve written a new more robust slideshow, along with a code walkthough/tutorial. If you’re looking for a slideshow to use on your own site, it’ll be better and easier to use than this one. Go check it out: http://themarklee.com/2014/10/05/better-simple-slideshow/

A while back I wrote about a technique for building a simple automatically cycling slideshow using CSS animations, no JavaScript required. While that is definitely an interesting technique, it’s also pretty limited in how you can use it. For example, often with an image slideshow rather than just auto-advancing the slides you may want to let the user have control, so they can navigate forwards and backwards through the images at their own pace. These days you also may want a slideshow that’s responsive, so that it will work across a wide range of devices, automatically resize to fit different screen sizes, and maybe even allow some more touch-centric interaction–like swiping to the left or right instead of clicking “previous” and “next” buttons to cycle through the slides.

If this is what you need and you’re just looking for a drop-in solution, there’s no reason to reinvent the wheel, there are some great slideshow options out there already (here are just a few: SwipeJS, SlidesJS). However if you’re more of the do-it-yourself type and you want to custom-build your own to suit your exact needs, or just want to see how it can be done, then it’s pretty easy to get started with just a little bit of HTML, CSS, and JavaScript.

Note: this is not going to be the be-all, end-all of javascript slideshows that will meet all of your needs and then some, but should be a nice, simple, starting point that you can use, extend, or throw away. The goal is just to show one approach toward building these things, and hopefully pick up a new trick or two along the way. Sound good? Then let’s roll :-) [See the demo or full finished code on GitHub]

The HTML Markup

Rather than just using divs or unordered list-items or whatever else we may have used in the past, let’s use the newer, shinier, and more semantic HTML5 elements figure and figcaption. Here’s what the markup looks like:
[html]

Image caption goes here.
Image caption goes here.

… more

s as needed«
»

[/html]

As you can see we’ve got the whole thing encapsulated in a div, then each image/caption combination lives inside a figure, and at the end comes a couple of spans that will be used for the navigation buttons. Only the first figure has a class of “show”, so that image will appear when the slideshow is first loaded. We’ll make that happen with the CSS. If you wanted to make the markup even simpler you could inject the “show” class and the navigation buttons with JavaScript, but I’ve opted to do as much as possible in the HTML/CSS.

The other thing of note here is that the slide s all have a width of 100%, which will help our slideshow be responsive right out of the gate. You’ll want to make sure all your images are the same size, and are large enough to look good at the widest size that the slideshow will appear. Yes, this will mean that file sizes are somewhat bigger than they need to be in most cases, but until responsive images are solved then tradeoffs need to be made, and in this case I’ve chosen simplicity at the cost of a little more page weight. If image file size is a concern though, this “compressive images” technique is worth looking at. It’s in Dutch, but Google translates it pretty well, or here’s an English writeup from Filament Group.

The CSS Styles

Now that the markup is built, we’re ready to start styling it. For now just ignore the little fiddly parts like the font-sizes and colors, the fundamentals of how this all works are in the position, the opacity, and the transition properties. I’ll explain the key parts below:
[css]
.diy-slideshow{
position: relative;
display: block;
overflow: hidden;
}
figure{
position: absolute;
opacity: 0;
transition: 1s opacity;
}
figcaption{
position: absolute;
font-family: sans-serif;
font-size: .8em;
bottom: .75em;
right: .35em;
padding: .25em;
color: #fff;
background: rgba(0,0,0, .25);
border-radius: 2px;
}
figcaption a{
color: #fff;
}
figure.show{
opacity: 1;
position: static;
transition: 1s opacity;
}
.next, .prev{
color: #fff;
position: absolute;
background: rgba(0,0,0, .6);
top: 50%;
z-index: 1;
font-size: 2em;
margin-top: -.75em;
opacity: .3;
user-select: none;
}
.next:hover, .prev:hover{
cursor: pointer;
opacity: 1;
}
.next{
right: 0;
padding: 10px 5px 15px 10px;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.prev{
left: 0;
padding: 10px 10px 15px 5px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
[/css]
Starting from the top, the .diy-slideshow element is positioned relative, because the all the figures are going to be absolutely positioned inside of it. (Here’s an article from a million years ago that explains relative+absolute positioning: Absolutely relative). The fact that the figures are all absolutely positioned makes them stack up one atop the other, like a deck of cards. Also because the figures all have an opacity of 0 they will be transparent, except the one with a class of .show which has an opacity of 1 and will be opaque.

Note that, as usual for clarity and brevity, I’ve only included the standard unprefixed W3C-approved properties in the example CSS. In production you may want to include prefixed versions of some properties as needed for cross-browser compatibility. See Chris Coyier’s article “How To Deal With Vendor Prefixes” for a good overview. Or use Autoprefixer.

The CSS transition

One nice thing about this approach to building a slideshow is that even though it uses javascript for class-switching the transitions between slides are handled with CSS, so it’s super-easy to swap the fade-in-out effect with some other transition. The key part here is the difference between the regular figure and the active/visible figure which has a class of “show”.

[css]
figure{
position: absolute;
opacity: 0;
transition: 1s opacity;
}
figure.show{
opacity: 1;
position: static;
transition: 1s opacity;
}
[/css]

The transition property makes the slides fade in and out nicely over 1 second as the “show” class is added to or removed from a figure. You can see how easy it would be to change the timing of the transition to make it faster or slower or add some easing with a timing function. And because we’ve added the transition property to both states, the default figure and the figure.show then the opacity transition happens when the class is added to the element AND when the class is removed, providing a nice-looking cross-fade.

The downside to this approach is more limited support in Internet Explorer land. CSS transitions are only supported by IE 10+. The good news is that CSS opacity is supported much further back so for earlier versions of IE the slideshow itself can be made to work, just without the nice opacity cross-fade effect.

The Javascript: jQuery version

Because all of the markup is in the HTML, and both the styling and the slide transitions are in the CSS, there’s very little left that we need Javascript for, basically just to keep track of which is the current slide, to assign a particular class, “show”, to the active slide (and remove that class from all others), and attach a couple of event handlers to the slideshow’s previous and next buttons.

First, we’ll declare a couple of variables, and grab and cache a jQuery collection of all the slides (which are figures in the HTML), and also get and cache the total number of slides.
[js]
var counter = 0, // to keep track of current slide
$items = $(‘.diy-slideshow figure’), // a collection of all of the slides, caching for performance
numItems = $items.length; // total number of slides
[/js]

Next we have a function, showCurrent(), which shows the correct slide when the user presses the next and previous buttons. It calculates the correct slide to show using the expression Math.abs(counter%numItems), which I should explain in more detail below.

[js]
/** this function is what cycles the slides,
showing the next or previous slide and hiding all the others **/
var showCurrent = function(){
// calculates the actual index of the element to show
var itemToShow = Math.abs(counter%numItems);
// remove .show from whichever element currently has it
$items.removeClass(‘show’);
// add .show only to the current slide
$items.eq(itemToShow).addClass(‘show’);
};
[/js]

The variable counter is basically keeping track of the net number of times the previous and next buttons have been clicked. So when the slideshow loads, counter is 0, but if you click “next” 8 times the counter increments to 1, 2, 3, 4, 5, 6, 7, and then ends up at counter == 8. Then if you click “previous” 10 times, counter will equal 7, 6, 5, 4, 3, 2, 1, 0, -1, and finally -2. So counter is keeping track of our place, but its value ends up going way past the actual number of slides, as well as dipping into negative numbers at times.

This is where Math.abs(counter%numItems) comes in, which first uses the remainder operator to convert the larger number that counter might hold to a number that maps to the index of one of the slides in our slideshow (the % is a.k.a. the modulus or modulo operator which is technically not exactly the same thing). Then because counter might contain a negative number, we pass it through Math.abs() to get its absolute (non-negative) value.

After that, the showCurrent() function removes the “show” class from all the slides, then adds it back only to the one that’s now the new current slide. It’s slightly inefficient to attempt to remove the class from all of the slides, but it’s also simpler in that it saves us from having to either keep track separately of which one was the previously visible slide, or to query the DOM for which element currently has the “show” class, just to remove it.

The last thing we need to do is attach event handlers to the previous and next buttons, which we will use jQuery’s on() method for, nice and easy. The handler functions simply increment or decrement the counter variable, then call the showCurrent() function which was described above.
[js]
// add click events to prev & next buttons
$(‘.next’).on(‘click’, function(){
counter++;
showCurrent();
});
$(‘.prev’).on(‘click’, function(){
counter–;
showCurrent();
});
[/js]

Here’s all the JavaScript together, without comments. Note how everything is wrapped in jQuery’s $(document).ready():
[js]
$(document).ready(function(){

var counter = 0,
$items = $(‘.diy-slideshow figure’),
numItems = $items.length;

var showCurrent = function(){
var itemToShow = Math.abs(counter%numItems);
$items.removeClass(‘show’);
$items.eq(itemToShow).addClass(‘show’);
};

$(‘.next’).on(‘click’, function(){
counter++;
showCurrent();
});

$(‘.prev’).on(‘click’, function(){
counter–;
showCurrent();
});

});
[/js]

Adding “swipe” for touch devices

While the previous and next buttons should work just fine on touch-capable devices, it might be nice to add some touch-friendly interactions, like allowing the user to swipe left and right through the slides. So if touch events are supported then we will add swipe events using the TouchSwipe jQuery plugin.
[js]
if(‘ontouchstart’ in window){
$(“.diy-slideshow”).swipe({
swipeLeft:function() {
counter++;
showCurrent();
},
swipeRight:function() {
counter–;
showCurrent();
}
});
}
[/js]

We’ll just leave the previous/next buttons with their click events in place too, because these days just because touch is supported doesn’t mean that the user is on a touch-only device.

The no-jQuery JavaScript version

The jQuery code above is easy to write, pretty simple and clear (if you know jQuery at all) and fairly cross-browser compatible, so if you’re building your slideshow for a site where jQuery is already being loaded and used, why not go that route? On the other hand, basically all we’re using jQuery for here is accessing DOM elements, attaching event handlers, and adding removing classes, all of which have become pretty simple to do in vanilla JavaScript in modern browsers. So if you don’t already need jQuery, want to remove it as a dependency, or just want to build it in a more “pure” library-free way, here’s the plain ol’ JavaScript version:
[js]
(function(){

var counter = 0,
$items = document.querySelectorAll(‘.diy-slideshow figure’),
numItems = $items.length;

var showCurrent = function(){
var itemToShow = Math.abs(counter%numItems);

[].forEach.call( $items, function(el){
el.classList.remove(‘show’);
});

$items[itemToShow].classList.add(‘show’);
};

document.querySelector(‘.next’).addEventListener(‘click’, function() {
counter++;
showCurrent();
}, false);

document.querySelector(‘.prev’).addEventListener(‘click’, function() {
counter–;
showCurrent();
}, false);

})();
[/js]

Key differences between the code above and the jQuery version include the use of querySelector() and querySelectorAll() for getting the DOM elements, using [].forEach.call() to iterate through the elements, using classList.add() and classList.remove() to add/remove the “show” class, and using addEventListener() to attach the event handlers. Some or most of those methods are only supported in modern browsers (in some cases IE10+) but I’ll include some good resources below that cover the legacy JavaScript approaches to accomplishing the same results.

The Finished Slideshow: CodePen Style (jQuery version)

Check out this Pen!

The Finished Slideshow: CodePen Style (vanilla JavaScript version)

Check out this Pen!

References, Resources, and Further Reading

Post featured image: Slide Projector by macattck, on Flickr.

UPDATE (5/31/14):

Wow! First of all I want to thank everyone who has visited, read this tutorial, played around with the code, implemented the slideshow on your own website, and commented below with questions, suggestions for improvement, and gratitude.

As I said in a comment below “When I originally wrote this I just spent an afternoon playing around with different techniques, and this seemed like a decent approach. I honestly never expected more than a few people, or a few dozen at most to ever see it, and definitely never meant it to be code that other people would put into production. But I’m really glad to have had a lot of people look at it, and use it, and give feedback on how it can be improved. It’s probably overdue for a new and improved version.”

So today I’d like to announce that there’s a whole new version in development, meant to be a more robust, full-featured, and production-ready slideshow that you can more easily use on your own site. At the moment I plan for the new version to be vanilla javascript, removing the dependency on jQuery. Here are the top to-do fixes/features, roughly in order of priority:

  1. fix the “flash” or “jump” that happens when you go from the last image to the first (see: http://themarklee.com/2013/12/26/simple-diy-responsive-slideshow-made-html5-css3-javascript/#comment-5566) DONE
  2. ability to have multiple slideshows on a page DONE
  3. auto-advancing slides, with pause on mouseover, and the option to automatically stop on the last slide DONE
  4. arrow-key events to advance the slides DONE
  5. full-screen toggle DONE
  6. add swipe events for touch devices to the no-jquery version DONE

Work is now complete on these new features and I’ll definitely make a new blog post soon, so use the “Subscribe via Email” box on the right-hand side above if you want to be notified you can see the blog post about it here: http://themarklee.com/2014/10/05/better-simple-slideshow/.

115 Replies to “A simple DIY responsive image slideshow made with HTML5, CSS3, and JavaScript”

      1. Hi Mark,
        thanks for your tutorial but does not work on the mobile touch … is enough to fill the plugin: jquery.touchSwipe.js or what should you do? am desperate thanks hello

  1. Great tutorial Mark! I had a little issue implementing it in my design but I got some help at CSS-tricks!
    One question, how would I make the slideshoow auto start?
    And for some reason slide #2seems to jump in instead of fading in like the others.

    Thanks in advance!

  2. Thanks Jean-Francois, glad you found it helpful!
    Do you want the slideshow to automatically advance, without the user clicking the “next” button? If so you could just add a timer to the javascript to automatically advance the slide every x milliseconds. I would do it like this (where 1500 is the number of milliseconds):

    window.setInterval(function(){
    counter++;
    showCurrent();
    }, 1500);

    See the javascript in this example: http://codepen.io/leemark/pen/qBJzj

    I don’t see the jumping you mention but do you see it in my codepen example or just in your page? What browser/version?

    1. Thanks for the quick reply Mark!
      I added the timer and it works great!
      But I see it on your codepen too, when the image of the person looking at the forest in the snow there is a slight jump when that slide is loaded.
      I use FF and chrome latest stable releases in win7.

      One last thing, I tried to add a stop on mouseover and it doesn’t work, here is my pen: http://codepen.io/GroovyMotion/pen/ufasG

      Thanks in advance!

      1. Hi Jean-Francois

        I have the same issue with the jumping on the last image (when itemToShow changes to 0).
        Did you already find a solution?
        I would be glad if you shared it with us.

        Thank you and thank you Mark for the great tutorial!
        Jo

        1. I would also love to figure this out, it only happens when it switches from the last slide back to the first slide (like you said when itemToShow changes to 0). From what I’ve seen so far it has to do with the CSS, and switching the figures between position:static and position:absolute. I’ll keep looking at it.

          1. All the figures need to be absolutely positioned (and other changes made to accommodate that: diy div no hidden overflow, etc.). The problem is that when the last figure in is switched from static to absolute, it immediately allows the background to be seen because there is nothing else below it.

      2. Jean, replace this:

        window.setInterval(function(){
        counter++;
        showCurrent();
        }, 1500);

        with this:

        interval = setInterval(function(){
        counter++;
        showCurrent();
        }, 1500);

        $(‘.diy-slideshow’).hover(function() {
        interval = clearInterval(interval);
        }, function() {
        interval = setInterval(function(){
        counter++;
        showCurrent();
        }, 1500);
        });

    2. Hi Mark,

      Thanks for adding the animation on the slides.
      Would you be able to let me know how can I stop the animation after the last slide?

      Thanks
      Puneet

  3. Hi Mark,

    I can’t seem to get the actual slides to move when I click next or prev.
    What have I missed?

    Thanks, otherwise, for a great tutorial!

    1. Hi Stefan, can you share a link to your slideshow (or email me at leemark@gmail.com)? If so I will take a look at it and see what’s going on. Are you using the jQuery version, and if so have you included the jQuery library? Just a total wild guess, I’d really need to see your slideshow or code to help troubleshoot.

  4. Dear Mark

    Thanks for your tutorial. it is very straight forward and useful!!!!!

    I have a question, in this sample, how to make the slide show move automatically without clicking anything?

    Best regards

    Mo

    1. Hi Mo,
      Here’s an example where someone took the javascript code in this post and implemented autoplay functionality, so the slides will automatically advance: http://www.kstb.de/slider/
      You can view the code there, but if you need more specifics just let me know!
      Mark

  5. Hi thanks for the code
    i would like that the background color change with pictures : every picture with a specific background color !! is it possible and how to do it plz

    1. Sure, you could make each <figure> have its own background color, and those should then each change along with the pictures. Would something like this work for you?

      figure:nth-child(1){background-color:#FFFFFF;}
      figure:nth-child(2){background-color:#00FFFF;}
      figure:nth-child(3){background-color:#FF00FF;}
      figure:nth-child(4){background-color:#FFFF00;}
      ... and so on

  6. Hey there,
    So this seems awesome but, its not working with me.
    css:

    .diy-slideshow{
    position: relative;
    //display: block;
    //overflow: hidden;
    }
    figure{
    position: absolute;
    opacity: 0;
    transition: 1s opacity;
    }
    figcaption{
    position: absolute;
    font-family: sans-serif;
    font-size: .8em;
    bottom: .75em;
    right: .35em;
    padding: .25em;
    color: #fff;
    background: rgba(0,0,0, .25);
    border-radius: 2px;
    margin-right: 50px;
    }
    figcaption a{
    color: #fff;
    }
    figure.show{
    opacity: 1;
    position: static;
    transition: 1s opacity;
    }
    .next, .prev{
    color: #fff;
    position: absolute;
    background: rgba(0,0,0, .6);
    top: 50%;
    z-index: 1;
    font-size: 2em;
    margin-top: -.75em;
    opacity: .3;
    user-select: none;
    }
    .next:hover, .prev:hover{
    cursor: pointer;
    opacity: 1;
    }
    .next{
    right: 0;
    padding: 10px 5px 15px 10px;
    border-top-left-radius: 3px;
    border-bottom-left-radius: 3px;
    }
    .prev{
    left: 0;
    padding: 10px 10px 15px 5px;
    border-top-right-radius: 3px;
    border-bottom-right-radius: 3px;
    }
    p{
    margin: 10px 20px;
    color: #fff;
    }

    html:

    "Snowying" by

    "Starlight" by

    «
    »


    script:

    (function(){

    var counter = 0, // to keep track of current slide
    $items = document.querySelectorAll('.diy-slideshow figure'), // a collection of all of the slides, caching for performance
    numItems = $items.length; // total number of slides

    // this function is what cycles the slides, showing the next or previous slide and hiding all the others
    var showCurrent = function(){
    var itemToShow = Math.abs(counter%numItems);// uses remainder (aka modulo) operator to get the actual index of the element to show

    // remove .show from whichever element currently has it
    // http://stackoverflow.com/a/16053538/2006057
    [].forEach.call( $items, function(el){
    el.classList.remove('show');
    });

    // add .show to the one item that's supposed to have it
    $items[itemToShow].classList.add('show');
    };

    // add click events to prev & next buttons
    document.querySelector('.next').addEventListener('click', function() {
    counter++;
    showCurrent();
    }, false);

    document.querySelector('.prev').addEventListener('click', function() {
    counter--;
    showCurrent();
    }, false);

    })();

  7. Hello Mark,

    thank you for your DIY responsive image slideshow.
    >really like the non jquery version, appreciate simple well coded solutions !

    Is there an easy way to implement arrow-key navigation for the .next & .prev classes ?

    best regards,

    andreas

  8. Hi Mark

    I have used the code for a website I am designing as part of a course and it worked beautifully – thank you. I added links in the figcaption to click through to the relevant sub pages but it only worked on the first slide.

    I would imagine that the reason for this is that the images are layered. Is there any workaround to enable links on all the slideshow images?

    Any help would be much appreciated

    Kind Regards

    1. Hi Amanda,
      I’m glad you found it useful, thank you!

      I suspect that what you’re seeing has something to do with the layering, like you suggest, however I have links in the captions as well that seem to work fine. Maybe it’s a browser difference (I’ve tested in Chrome and FF), but do the links in the captions work correctly for you in this codepen example? http://codepen.io/leemark/pen/DLgbr

      If the links work right for you in the codepen example, but not in yours, I would look to see whether there are any key differences between your code and mine. If they also don’t work for you in my codepen example then could you let me know the OS. browser, and browser version you are using and I’ll investigate further.

  9. hello,

    thank you for a very versatile and easy to use image slideshow !

    Q:
    is there a good way to add keyboard navigation for “next” and “previous” ?

    best regards from Paris,

    andreas

    1. Hi Andreas,
      What you want to do is listen for keypresses, then when a key is pressed, test whether it’s the left arrow key (keycode:37) or the right arrow key (keycode:39). If so, either increment or decrement the counter accordingly, and call the showCurrent() function. Here’s how to do it in jQuery:

      $('html').keydown(function(e){
      if(e.which === 37){
      counter--;
      showCurrent();
      } else if (e.which === 39){
      counter++;
      showCurrent();
      }
      });

      1. hello Mark,

        appreciate your help ! thank you very much!
        is the code much different without jQuery ?

        i use the non-version jQuery of the slideshow.
        my current implementation can be seen here:
        http://aranaa.fr/diy-slideshow-paris.html

        also wonder about mobile device “touch” function, would that be difficult associate with the “counter-showCurrent” function ? Maybe listen for “swipe letf/right” then activate “counter-showCurrent” ?

        best regards,

        andreas

        1. Oh yes, if you’re not using jQuery then the plain javascript version will be very similar. There’s an example given here that will work for you with only slight modification (use right/left keycodes instead of up/down): http://stackoverflow.com/questions/5597060/detecting-arrow-key-presses-in-javascript

          As far as detecting swipe events on touch devices, that’s totally doable, it just gets a little complicated because there are no native “swipe” events (see: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent), so what you have to do is listen for other events like touchstart, touchmove, and touchend, then calculate for yourself whether a “swipe left” or “swipe right” has occurred. You might consider using a library for that, like hammer.js (no-jQuery required) or TouchSwipe (jQuery plugin). But you could definitely write your own swipe detection if you wanted to. Here’s a tutorial that includes a section on detecting swipes: http://www.javascriptkit.com/javatutors/touchevents.shtml.

          1. Thanks for your insight !

            as i’m not really clever with code, i looked through the stackoverflow article and tried the following without success :
            document.onkeydown = checkKey;
            document.onkeypress = checkKey;

            function checkKey(e) {

            e = e || window.event;

            if (e.keyCode == '37') {
            counter++;
            showCurrent();
            }
            else if (e.keyCode == '39') {
            counter--;
            showCurrent();
            }
            }

            would this code be close to working or am i way off ?

            best rgds,

            andreas

          2. That looks pretty much correct to me. Check out this codepen, which is working for me: http://codepen.io/leemark/pen/eCnvJ. To try it out you may have to click your mouse in the slideshow window first before the keyboard navigation will work, but that’s just because it’s inside an iframe on codepen. It’s lines 32-42 in the javascript, I just shortened it up a bit because you only need onkeydown.

          3. Hi!

            very nice !

            i have it working too ! i made some mistakes in the order & with the end “signs” })();

            i really like your script and would be very cool to develop it even further as you hinted to. especially the non jQuery version !

            thanks & best regards,

            andreas

      2. Hi Mr. Mark thank you for the big help! I’m trouble in working for a pause button, if it is possible, hope anyone can help me.

  10. Hi
    Nice simple tutorial, thanks. Couldn’t get it to work locally at first but found out it was because of the missing http:// on the googleapis link.
    One question though: the transitions in the forward direction are smooth and slow but on the previous (back) direction they are abrupt and quicker. Why is that?
    Cheers

    1. Yeah, the scheme relative URL has tripped me up too when working locally. I should probably just go with http:// for example code.

      I’m not sure about the transition issue you are seeing, where going forward is smooth but going backward is abrupt. I don’t see that in my browser, but it doesn’t surprise me that it’s a little janky. I think the entire CSS here could benefit from a rethinking on how all the images are positioned and how the transitions are accomplished.

      When I originally wrote this I just spent an afternoon playing around with different techniques, and this seemed like a decent approach. I honestly never expected more than a few people, or a few dozen at most to ever see it, and definitely never meant it to be code that other people would put into production. But I’m really glad to have had a lot of people look at it, and use it, and give feedback on how it can be improved. It’s probably overdue for a new and improved version.

  11. Mark, thank you for this great slideshow!
    I’m working with the no-jquery version, but only one slideshow works on any given page. Is there any tweak for this? I’d like to have a few in a row. Thanks for your help!!

    1. Hi Rachel! This is definitely do-able. I will have a new version out soon that will address this and a few other needed features. Please see this update , and stay tuned :)

  12. Hello,

    thanks once more for your DIY slideshow and advice.
    i’m in the same situation as Rachel whereas i’m working with the non-jquery version and would like to use several slideshows in a one-page webdesign,,,
    i’ve managed to make several slideshows work, but the code seems quite redundant as i multiply the javascript code, and just use new classes for each “figure” tag and navigation tag,,, (‘slide1 figure’ & ‘next1’/’prev1’ etc).

    would be great to have a more efficient way of implenting multiple slideshows !


      1. Hi Mark !
        that is great news ! Look forward to the new version of the DIY slideshow, especially the no-jquery version :)

        The “one more thing” question for me personnally is the implementation of responsive images & multiple assets for different screens/resolutions,,,

        what are your thoughts on best practice for optimising display across devices?

        best rgds,

        andreas
        An Interesting Article from Smashing Magazine

  13. Mark,

    Mark first and foremost thank you.

    Have you found a solution to the jump/pop on the last slide transition?
    I second Andrea’s request for the ability to have multiple slideshows without making redundant code.

    Thank you again.

  14. Mark,

    You have your work cut out for you, I just read your update list. If you have a PayPal donation link I would be happy to contribute. Again I appreciate you sharing… it would be great to see your code with comments – it helps to learn what is going on.

    I’ve been working with HTML and CSS for a few months now but what I really need to do is start to learn Javascript/JQuery. Do you have any book/or website recommendations? I have been using Jon Duckett’s HTML & CSS book, I like it so much I have pre ordered his javascript book.

    Thanks again, I look forward to seeing your latest DIY slideshow.

    Have a great weekend.

    All the Best.

    1. Thanks Jim! I’m not currently taking donations, but I definitely appreciate the offer! This work is pretty intrinsically rewarding, I’ve learned a lot just responding to people’s questions and researching how to implement improvements.

      About learning jQuery and JavaScript, I can suggest a couple of things that have worked well for me.
      Codecademy’s JavaScript track – Good for just starting out with JavaScript, getting used to looking at, writing, and understanding basic JS language features and code. After finishing this I still felt like a beginner, but a much stronger beginner.
      30 Days to Learn jQuery – free but requires registration. This course is a great beginner-to-intermediate overview of jQuery, and Jeffrey Way goes beyond “here’s a way to do X in JQuery” to “here’s the right way to do X in JQuery (and javascript in general), and here’s why it’s the right way”.
      Eloquent JavaScript – a great online interactive book, after getting through most of this I felt like I was really starting to understand JavaScript.
      Codewars – challenges or puzzles to test and stretch your JS knowledge
      Crockford on JavaScript – I also watched this lecture series a few times through, covers where JS came from, why it is the way it is, and why it’s actually a pretty cool language.

      1. Mark,

        Thanks again, I will be sure to check out the books/sites you suggested. You are being very gracious with your time, if you were to put up a donation link I believe a number of us would be happy to contribute.

        I look forward to your slideshow update.

        All the Best,

        Jim

      2. Mark,

        I just wanted to say thank you again. It looks like you are making some great progress with the new version/features. I really appreciate the time and effort you are putting into this. I look forward to the final version.

  15. Great tutorial, but how can I get the navigation button to be outside of the slider and not on top of the images?

  16. Hello Mark,
    Sorry I am a newbie and I don’t know where to place the JS code :\ I placed the HTML and it worked, but no movement in the sildeshow so the Java, where should it go?

  17. hi mark,

    I am using the javascript version and i am getting this error in js code at line:

    document.querySelector(‘.next’).addEventListener(‘click’, function () {

    Error:Cannot call method ‘addEventListener’ of null

    Can you please help

  18. Hey Mark, Thanks for the simple slideshow.

    I like the clean CSS codes; However for some reason the JQuery nor the non-JQuery codes is working for me. The next and prev buttons does not appear at all.

    is there an update for this slideshow tutorial???

    Thanks..

  19. Wonderful slideshow, decided to use the newer version to have multiple slideshows per page, got it working nicely, and then tested it on IE. It doesn’t like querySelectorAll and the slideshow died. Any suggestions on using jQuery to deal with that?

    1. Hi Ken,
      It should work on IE10+ out-of-the-box, but let me know if it doesn’t. I believe you can easily get IE9 support by including this shim for classList: https://github.com/eligrey/classList.js. You might be able to get it working on IE8 by including these additional shims/polyfills to add the necessary methods that IE8 lacks:

      But querySelectorAll should already work in IE8+, so I suspect you are looking for IE7 (orIE6) support, right? I want to make this work in IE9+ but supporting really old IE versions is probably a bridge too far for a little script like this. It’d probably be smarter to just port the new script (https://github.com/leemark/better-simple-slideshow) to jQuery, or to add multiple-slideshow support to the original jQuery version. I could help you look at that last option if you’re interested, and not in too big a hurry :)

      1. I’m starting to check out one of the sites you referenced: http://code.tutsplus.com/tutorials/from-jquery-to-javascript-a-reference–net-23703

        I’m hoping to follow these guidelines to use old style ;-) javascript to replace the queries. I’m updating a very old website and was using IE 11. I replaced the DOCTYPE declaration as HTML5 but other stuff in there may have triggered some form of quirks mode. All I really know is it didn’t work, so I jumped to conclusions and started replacing the part it complained about–the queryselectall().

        1. Found a few interesting things. First, IE automatically treats pages on an intranet (which is what my XAMPP server is) as suspect and applies Compatibility View. Having stopped that, it now works fine in IE 10 & 11, but everything less is unusable. If I want to reach the regrettably large percent still using the dinosaur, I still have to replace the querySelect parts of the script.

          I’ve also begun to suspect your implementation of multiple slideshows is a work in progress. In calling makeBBS each slideshow in your example page has a unique class (!) to allow unique options. This makes me wonder if I can safely call slideshows with the same options using the same class. I’ll get back to you ;-)

          1. To stop the vertical jump when returning to the first slide I changed some css:
            .bss-slides figure:first-child{
            position: relative;
            top: 12px;
            }

  20. Hi, I followed your logic to make a picture slideshow in my upcoming portfolio. I had to make some modifications such as generating automatic bullet points under the slider and I love it. I came across one bug in your code that becomes very apparent when having those bullets. Your slideshow is not listing slides in proper order (test it – if you hit next we find that the second slide is snowflake, if instead you hit back, changing counter to -1 it still shows the snowflake). With some research I’ve found it’s a known bug in how javascript is handling modulo of negative values. To fix it change: var itemToShow = ((counter%numItems)+numItems)%numItems;

  21. Hello Mark, Great tutorial.
    I kind of started to create a slide show like yours but it uses a plugin which I don’t want to deal with in the future.

    What I am doing is, instead of use it as a slideshow, I want to use it as a photo gallery. The slideshow window is for big pictures and on the bottom to have the thumbnail with many pictures. Perhaps the over floating set it as hidden.

    Is there an easy way to do this without the plugin?

    Thank you for your help!!

    Roberto.

  22. So, this all went really well until the JavaScript portion. Can you dumb it down a bit for those of us who struggle with JS?

  23. Mark,

    Thanks for all your hard work with this slideshow.

    I set everything up as outlined and it works great on my desktop browsers but I have to provide support for a number of older Android devices.

    I was wondering how I could get this to work with Android v2.3.6? Your demo page for the new slideshow has the same problem as mine, neither of the sideshows actually show.

    The older slideshow with the touch polyfill is working for now I would like to take advantage of the new version if I can. I downloaded Android’s SDK but I’m getting in way over my head… thank for any help you may provide.

    All the Best

  24. Mark,
    Thanks for sharing, your a great resource..

    Areg

    Now if I can get the the next and previous arrows to vertically float I would be set

    1. Mark,
      Is it possible to link to a specific image in the slideshow, such that the slideshow starts with image 4 instead of image 1? My experience with code is not that great and the only solution I came up with was a separate slideshow for each image. Any guidance would be appreciated.

  25. Dear Marklee:

    Thanks, your tutorial is very useful and helpful, but I have encounter a problem. I have applied your method with CSS and JQUery, the slideshow works perfectly but the position of the banner which contains slideshow has totally changed and makes the layout of the page look very odd. (I have provided the link of the page, please take a look)

    I have tried my best but I just can’t fix the position, could you have a look for me?
    The position of the banner before the slide show was added:
    http://www.monaking.co.uk/spidersweb/
    After the slide show was added:
    http://www.monaking.co.uk/spidersweb/index02.html

    All I want is to correct the position of the banner.

    Please take a look at my codes here:
    → (#banner is the div that contains the slideshow; #banner_container is the wrapper for #banner and the slideshow)
    #banner {
    position: absolute;
    top: 0px;
    left: 00px;
    }
    #banner_container {
    height: 265px;
    width: 708px;
    margin:0 auto;
    }
    ————————————————————————————————————–
    →(The following codes are mainly from your tutorial)
    .diy-slideshow{
    position: relative;

    display: block;
    overflow: hidden;
    }
    figure{
    position: absolute;
    opacity: 0;
    transition: 1s opacity;

    }

    figure.show{
    opacity: 1;
    position: static;
    transition: 1s opacity;
    }
    .next, .prev{
    color: #fff;
    position: absolute;
    background: rgba(0,0,0, .6);
    top: 50%;
    z-index: 1;
    font-size: 2em;
    margin-top: -.75em;
    opacity: .3;
    user-select: none;
    }
    .next:hover, .prev:hover{
    cursor: pointer;
    opacity: 1;
    }
    .next{
    right: 50;
    padding: 10px 5px 15px 10px;
    border-top-left-radius: 3px;
    border-bottom-left-radius: 3px;
    }
    .prev{
    left: 50;
    padding: 10px 10px 15px 5px;
    border-top-right-radius: 3px;
    border-bottom-right-radius: 3px;
    }
    ——————————————————————————————————-
    →(Please also check html part of it, again, it is mainly applied from your tutorial)

    «
    »

    —————————————————————————————————————-
    Best regards
    Madhuri

  26. Dear Marklee, it seems that the html part wasn’t shown in my previous message, so I hereby copy again.

    «
    »

    Best regards

    Madhuri

  27. hey Mark,
    Thanks for the tutorial!! But the next and previous buttons are not seen in my app.. Did I miss out anything?

  28. Hi,

    Thanks! this is awesome! however i was trying to use this as is for test purposes, i copied the exact code but the buttons dont work, it only display the first pic nothing else..

    Can you help me?

  29. Thanks for posting this Mark — it is just what I have been looking for. Simple and clean without a lot of wild animations. Please forgive my ignorance, but I have been trying to place this slideshow into a popup window and I can’t get it to work. The image comes up, as well as the previous and next buttons (with rollovers), but I can’t get it to advance to the next image.

    Any thoughts you might have would be greatly appreciated.

    Thanks,
    John

  30. Hi Mark,

    This tutorial seems quite useful, nevertheless, I have a problem with the vertical jumping of the images when using the buttons. Could you tell me where the problem lies?

    Many thanks & best regards,
    Michaela

  31. Hello mark!

    Thank you so much for this tutorial. I am having trouble with the next and previous buttons to work. They show up, although they need some placement tweaking, but they do not work as intended. Could you help me out?

    The site I am doing this for is http://www.eberly.iup.edu/ASCWeb/

  32. Hi Mark
    Thanks for the tutorial.
    Still got some reading to do but your tutorial has been a great help to me
    Regards
    Etienne, Tjon Sjoe Sjoe

  33. Hi Mark,

    thank you for this nice tutorial for building a slideshow.

    the slideshow shows up correctly on my page.
    but i cant navigate with the arrows (next, previous).

    here is how i build it up on my page:

    “Snowying” by fiddleoak.

    “Starlight” by ChaoticMind75.

    “Snowstorm” by Beaulawrence.

    «
    »

    Its an HTML5 Page based on ASP.net, with a master page.

    would be glad if you got the time to help me.

    thank you & kind regards
    Mike

  34. Hello Mark,

    I like your simple image gallery. I have one page website and would like to have 3 galleries in it. With your code works only one, maybe you could assist me on how to make the rest working?

    Best regards,
    Elas

  35. This DIY Slideshow is pretty cool stuff. I got a problem, my parameters for use are 600 450. It looks great in live mode on Dreamweaver (like it’s supposed to), but in all browsers, it kicks the arrows out of the picture and kicks the figcaption below the image. Any comments as to why it’s doing that are appreciated. Thanks!

  36. Hi,

    where do we need to place the javascript ? is it in the body part of the html file or in the head ?

    my css is an external link.

  37. Hi there, Im pretty new to learning about javascript, I was wondering if you could tell me how I could get a second gallery to work on the same page using the javascript model.
    Thanks,
    Jessie

  38. Nice slideshow.But it is not working offline.so many js I am quite new and get confused.Is it necessary to have so much js just to run this slideshow,can the code be reduced.pl advise.
    Thanks

  39. Immer wieder perfekt!
    I’m exchanging more and more of these overwhelming slideshows against the Better Simple Slideshow. No trouble anywhere, fits perfectly in any design, no collisions with any other css or js. Thank you Mark!

  40. Good day Mark! Thanks again for creating this Slideshow. It’s quite great.
    I was wondering if you would be able to help me with some changes. I don’t have a strong enough grasp of JS to make the changes that I would like to do. We could arrange something through PayPal, if you’d like. Thanks again.

    1. Hi Dario! Feel free to reach out via email: leemark @ gmail.com, I’m interested to hear more about what changes or improvements you’re looking for, and I may be able to help!

  41. Hello mark
    first of all thank you for your image slideshow
    i use (jQuery version)
    but i want to use couple of sliders on one page and have problem with listing of more than one slider
    for example

    how i solve like this problem
    thank you and have a good day

  42. I have all the code and it all works EXCEPT when I click the arrows, it does not change the slide. I essentially just copied the code, but took out the captions as I don’t want to use them. I have been searching for a good, simple slideshow and yours by far works the best but I just can’t get the image to change when I press the previous or next buttons.

  43. Copying non-JQuery version from CodePen (where it works) with latest Chrome I get “Uncaught type error: Cannot read property ‘addEventListener’ of null”. I do have “prev” and “null” in html body.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.