Responsive jQuery Image Gallery with Slideshow without Plugin

jQuery and CSS3 have provided great capabilities to web designers and developers to create stunning graphics and effects. If you are looking for creating an Image Gallery with overlay image, there are several plugins like Lightbox and Fancybox which can do this task for you. You need to include the plugin in your project and follow the simple instruction to make your image gallery come to life.

But can we achieve the similar Lightbox effect without using any jQuery plugin? In this tutorial, I will take you through creating an advanced fancy Image Gallery with similar functionalities with no plugin. The best part is that the codes are really simple to understand and you can customize the look entirely with the CSS. Here are some of the salient features of this image gallery with auto slider.

  • Lightbox style image overlay effect without any plugin
  • Keyboard control for previous, next and close functions
  • Responsive slideshow – Fits in all screen sizes
  • Auto Slideshow with an option to pause and play
  • Information about the picture being viewed
  • Simple and clean HTML mark-up without any extra attribute
  • Fully customizable with CSS and JavaScript codes
  • Lightweight and easy to implement
  • Fancy imageless buttons

jquery-slideshow

Enough! Best to have a look what we are going to create at the end of this article.

Demo                    Download the Source Files

For creating this cool image gallery with slider, we will use HTML, CSS and JavaScript. I will try to explain everything in details so that you can easily understand the behind the scene happenings. Just stay tuned till the end.

HTML

We will start with the simplest part – the HTML. There is nothing special in the HTML codes.

        <div>
            <ul>
                <li>
                    <img src="images/1.jpg" alt="Autumn Leaves" /></li>
                <li>
                    <img src="images/2.jpg" alt="Chameleon in Mood" /></li>
                <li>
                    <img src="images/3.jpg" alt="Beautiful Insect" /></li>
                <li>
                    <img src="images/4.jpg" alt="Happy Flowers" /></li>
                <li>
                    <img src="images/5.jpg" alt="Its Spring Again" /></li>
                <li>
                    <img src="images/6.jpg" alt="Not just Yummy" /></li>
            </ul>
        </div>
        <div id="viewer">
            <a id="link-img">
                <img id="viewer-img" />
            </a>
            <span id="cross" title="Close" aria-hidden="true" class="icon-close"></span>
            <span id="img-name"></span>
            <span id="previous" title="Previous" aria-hidden="true" class="icon-previous"></span>
            <span id="next" title="next" aria-hidden="true" class="icon-next"></span>
            <span id="pause" title="Pause Slideshow" aria-hidden="true"></span>
            <span id="play" title="Start Slideshow" aria-hidden="true"></span>
        </div>

There are two major sections here – first contains the image thumbnails and other the slideshow part. The div with “demo” class contains all the images to create the gallery which are kept as list items in an unordered list. Note that the alt attribute of images will be used as the caption. The second div with “viewer” id contains all the elements of the slideshow. The image with “viewer-img” id is the overlay image currently being displayed in slideshow. It is put inside the hyperlink with id “link_image”. The image “src” and “href “attribute are assigned on the fly after start of the slideshow. Below this are all the buttons and caption as spans with IDs which are self explanatory. The span with “img-name” is used to display the caption. I have used IcoMoon icon-fonts here for displaying the icons as done in my article animated social media menu.

That’s all for the html part. You can add as many images as you wish. But it is better to use the images of same width and height. Otherwise also, we will specifically define the height and width for the thumbnails. If the variation of height to width ratio between images is high, the picture may look a little stretched.

CSS

Let’s first style the thumbnail container and the image thumbnails. The CSS code below is used to do the layout and style the image gallery with thumbnails.

.demo
{
    width: 900px;
    margin: 20px auto;
    position: relative;
}
.demo ul
{
    padding: 0;
    list-style: none;
}
.demo li
{
    float: left;
}
.demo li img
{
    width: 300px;   
    height: 200px;
    display: block;
    opacity: 0.8;
    transition: .3s;
}
.demo ul:hover img
{
    opacity: 0.6;
    cursor: pointer;
}
.demo ul:hover img:hover
{
    opacity: 1;
}

Initially, all the image thumbnails (defined inside the list items) are a little transparent (opacity 0.8). This transparency increases a little more (opacity 0.6) when you rollover your mouse to any of the image inside the gallery. However, the image where the mouse is hovered becomes totally opaque (opacity 1) making it stand out from the rest.  We have defined a transition interval of 0.3 second to animate the effects.

The next set of codes actually lays down the foundation of slideshow.

#viewer
{
    z-index: 10;
    position: fixed;   
    display: none;
    overflow: hidden;
}
#viewer-img
{
    border: 5px solid #FFFFFF;
    width: 500px;
}
#viewer span
{
    padding: 10px;
    position: absolute;
    font-size: 20px;
    z-index: 11;
    background-color: #FFFFFF;
    cursor: pointer;
    border-radius: 50%;
    opacity: 0;   
    transition: .3s;
}
#viewer span:hover
{
    box-shadow: 0px 0px 5px 2px #333333;
}
#viewer:hover span
{
    opacity: 1;
}

We are defining the z-index for “viewer” ID which is used to display the overlay image to 10 making it come on top of the elements used to create the image gallery. The position is defined as fixed because we want it to keep in the centre of the viewport. The left and top property of “viewer” will be defined on the fly with jQuery. This is because we want to make it responsive and change the position and size according to the viewport. The “viewer” is initially not displayed (display:none) and only appears after we click on any thumbnail image. The overflow property is set to hidden so that any item which is outside the boundary of “viewer” will be hidden. It will be used to create the fancy animation on control buttons.

The width of the image is defined as 500px with a white border of 5px.

CSS properties of all the buttons and the caption are defined at one go inside #viewer span. On mouse-hover, a subtle shadow appears on each of these buttons. These button are initially totally transparent to all the uninterrupted view of the image being viewed and becomes visible only when you rollover your mouse to it.

The last set of CSS codes actually defines the positions and properties of all the buttons and caption.

#viewer #cross
{
    top: 0px;
    right: 10px;
}
#viewer #previous
{
    top: 150px;
    left: -20px;
}
#viewer #next
{
    top: 150px;
    right: -20px;
}
#viewer #pause, #play
{
    bottom: 20px;
    left: 250px;
}
#pause
{
       display: none;
}

#viewer #img-name
{   
    bottom: 30px;
    left: -200px;
    font-size: 14px;
    text-align: left;
    border-radius: 0 5px 5px 0;   
    transition: .5s;
} 
#viewer:hover #cross
{
    top: 10px;
}
#viewer:hover #previous
{
    left: 10px;
}
#viewer:hover #next
{
    right: 10px;
}
#viewer:hover #img-name
{
    left: 5px;
}

Most of the codes are used to define the normal and hovered positions of buttons and are easy to understand, I will describe here only the important elements.

The position properties (left, right, top, bottom) which are defined negative are initially outside the boundary of “viewer” and hence hidden. Once you rollover your mouse on “viewer”, these properties changes making them appear to fly-in.

Pause and Play buttons are kept at the same position. Initially the pause button is hidden and we toggle between pause and play programmatically.

You can note that the transition delay of “img-name” is 0.5 which is more than other buttons. This is done intentionally to make caption appear a little time after the other buttons. Also note the border-radius of “img-name” as “0 5px 5px 0” which makes the rounded corners only at right side.

jQuery (JavaScript)

Now let’s move to the most interesting part of this tutorial – i.e. jQuery.

First of all we will set the position of the overlay image with respect to viewport.

     var viewportWidth = $(window).width();
            var viewportHeight = $(window).height();

            $("#viewer").css("top", ((viewportHeight / 2) - 150) + "px");
            $("#viewer").css("left", ((viewportWidth / 2) - 250) + "px");

In normal condition, the top left corner of the slideshow picture is set 150 pixels above and 250 pixels left from the center of the viewport. Since our image width is 500px; the slideshow is displayed just in the middle of the screen.

css-image-gallery

Next lines of code actually start the image overlay and create the stage for slideshow when any thumbnail image is clicked.

            var i;     
            var count = $(".demo ul li").length;

            $(".demo li img").click(function () {
                $(".demo ul").css("opacity", 0.2);
                $("#viewer").css("display", "block");
                i = $(".demo li img").index(this) + 1;
                img_slideshow();
            });

             function img_slideshow() {
                var curr_img = $(".demo li:nth-child(" + i + ") > img");

                $("#viewer-img").attr("src", curr_img.attr("src"));
                $("#viewer-img").fadeOut(0);
                $("#viewer-img").fadeIn(500);
                $("#img-name").text(curr_img.attr("alt") + " - [#" + i + " of " + count + "]");
                $("#link-img").attr("href", curr_img.attr("src"));
            };

Variable “i” is used to store the index of the image currently being displayed. Variable “count” is for storing the total number of images inside the unordered list.

When any image from the gallery is clicked, the following actions take place.

  1. All the thumbnail images inside unordered list become almost transparent (opacity 0.2)
  2. The image overlay (“viewer”) appears (display:block)
  3. The index of image which is clicked is stored in variable “i”
  4. The slideshow function executes

Note here that the current position of image is added by 1. This is because, jQuery starts indexing from 0. However, in the slideshow function we will use the nth-child method to display the previous or next image. But the nth-child method starts indexing from 1.

The slideshow function is responsible for selecting and displaying the current image, doing the fade-in and fade-out animation, displaying the caption and setting the “href” attribute to the link.

Let’s define what to do when previous, next and close buttons are clicked.

     $("#previous").click(function () {
                previous_image();
            });

            $("#next").click(function () {
                next_image();
            });

            $("#cross").click(function () {
                close_viewer();
            });

            function previous_image() {
                if (i > 1) {
                    i = i - 1;
                }
                else {
                    i = count;
                };
                img_slideshow();
            };
            function next_image() {
                if (i < count) {
                    i = i + 1;
                }
                else {
                    i = 1;
                };
                img_slideshow();
            };
            function close_viewer() {
                $("#viewer").css("display", "none");
                $(".demo ul").css("opacity", 1);
            };

When previous button is clicked, it checks if the current image is not at start position (value of “i” greater than one). If yes, it simply increments it by one otherwise sets it to the end position. Then the slideshow function executes. Similarly, when the next button is pressed, the function checks if the current image is not at the end position (value of “i” less than “count”). If yes, it decrements it by one otherwise sets it to the initial position. This ensures that the slideshow runs continuously.

When close button is clicked, the “viewer” becomes hidden and the image gallery appears.

In next lines of code, we create the previous, next and Esc keys live for doing the same actions.

            $(document).keypress(function (e) {
                if (e.keyCode == 37) {
                    previous_image();
                }
                if (e.keyCode == 39) {
                    next_image();
                }
                if (e.keyCode == 27) {
                    close_viewer();
                }
            });

Our basic functionality is complete. Let’s make the image in slideshow responsive.

            $(window).resize(function () {
                viewportWidth = $(window).width();
                viewportHeight = $(window).height();
                $("#viewer").css("top", ((viewportHeight / 2) - 150) + "px");
                $("#viewer").css("left", ((viewportWidth / 2) - 250) + "px");
                if (viewportWidth < 500) {
                    $("#viewer").css("left", "0px");
                    $("#viewer").css("width", viewportWidth + "px");
                    $("#viewer-img").css("width", (viewportWidth - 10) + "px");
                };
            });

When the window is resized; the position of the slideshow changes accordingly. If the width of viewport is less than the width of image being displayed (500 px), the images size becomes 10 pixels less than the viewport width and the gap between the left edge of the viewport and image is reduced to zero.

The last part is to set the auto slideshow with start and pause buttons. I am thankful to tutorialzine.com from where I have learnt the concept of setting auto slideshow.

$('#play').click(function (e, simulated) {
                if (!simulated) {
                    autoAdvance();
                    $("#pause").css("display", "block");
                    $("#play").css("display", "none");
                }
            });

            function autoAdvance() {
                $('#next').trigger('click', [true]);
                timeOut = setTimeout(autoAdvance, 3000);
            };

            var timeOut = null;
            $('#pause, #previous, #next, #cross').click(function (e, simulated) {
                if (!simulated) {
                    clearTimeout(timeOut);
                    $("#pause").css("display", "none");
                    $("#play").css("display", "block");
                }
            });

The idea is to trigger the next button automatically at a set time interval. When play button is clicked, it disappears and pause button appears. At the same time autoAdvance function is executed which sets the trigger for next button at every 3000 ms (3 seconds).

When any of pause, previous, next or close buttons are clicked, the pause button disappears and play button appears. At the same time, Time out is set to null making the slideshow pause.

Conclusion

In this article, we created a fully responsive image gallery with slideshow capabilities without using any jQuery plugin. It is complete with the play-pause button and reacts with key press. It is fully customizable and you can use any number of images.

Feel free to grab the codes and use it in your actual projects. If you find it useful, please mention it on your blog and share it with your followers. You should link directly to this page and not to the downloadable files directly. Please let me know your feedback and how we can further improve this jQuery image gallery.

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>