Tabbed slideshow that works with and without JavaScript (jQuery)

Build an Auto-Scrolling Slideshow That Works With and Without JavaScript

Tutorial Details
  • Technologies: JavaScript, CSS
  • Difficulty: Intermediate
  • Completion Time: 1-2 hours

Create a jQuery slideshow that enables you to click through each slide when JavaScript is disabled, without having to display all slides one under the other.



Introduction

Final Product

There are several tutorials that walk people through how to create a jQuery slideshow, but there aren’t many
that focus on making it function without JavaScript. This is because most people believe it isn’t possible but
I am going to explain an exceedingly simple method that shows it is indeed possible. You’ll soon be
kicking yourself and asking “How did I not think of that?”…

In this tutorial I will cover the following:


Step 1: Writing the markup

First things first, we need to write the markup that our slideshow will use. So let’s jump straight
in and code it up:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>Tabbed jQuery slideshow</title>
        
        <link rel="stylesheet" href="css/slideshow.css" type="text/css" media="screen" />        
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
    </head>
    <body>
        <div id="slideshow">
            <div class="slides">
                <ul>
                    <li>
                        <h2>Slide one</h2>
                        <p>
                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
                            Donec pretium arcu non velit. Phasellus adipiscing auctor 
                            lorem. Curabitur in urna ut purus consequat sollicitudin. 
                            Phasellus ut diam. Cras magna libero, tempor id, venenatis 
                            sit amet, venenatis et, dui.
                        </p>
                    </li>
                    <li>
                        <h2>Slide two</h2>
                        <p>
                            Nam ac nibh sit amet augue ultricies sagittis. Donec sit 
                            amet nunc. Vivamus lacinia, nisi ac tincidunt commodo, purus 
                            nisi condimentum urna, sit amet molestie odio dolor non lectus. 
                            Cum sociis natoque penatibus et magnis dis parturient montes, 
                            nascetur ridiculus mus.
                        </p>
                    </li>   
                    <li>
                        <h2>Slide three</h2>
                        <p>
                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
                            Suspendisse adipiscing dui a nibh. Integer tristique lorem 
                            vitae massa. Etiam dapibus, eros sit amet euismod semper, 
                            felis erat congue lacus, sed aliquam metus libero sed elit.
                        </p>
                    </li>                
                </ul>
            </div>
            <ul class="slides-nav">
                <li><a href="#">Slide one</a></li>
                <li><a href="#">Slide two</a></li>
                <li><a href="#">Slide three</a></li>
            </ul>
        </div>
    </body>
</html>   

This isn’t quite complete yet but as a general rule of thumb, we should
always start with the bare minimum and enhance/add to it when
necessary.


Step 2: Add some CSS

We’re not going to be creating the most beautiful slideshow today as I
just want to demonstrate the functionality more than anything. The
following styles will set up our slideshow ready for action:

/* ---------------------------------------------------- */
/* GLOBAL
/* ---------------------------------------------------- */
html {
font-size: 76%;}

body {
font-family: arial, helvetica, sans-serif;
line-height: 1.4em;
font-size: 1.2em;
padding: 5%;}

/* ---------------------------------------------------- */
/* SLIDESHOW
/* ---------------------------------------------------- */
#slideshow {
width: 960px;
background-color: #eee;
border: 1px solid #ddd;}

#slideshow ul {
margin: 0;
padding: 0;
list-style-type: none;
height: 1%; /* IE fix */}

#slideshow ul:after {
content: ".";
clear: both;
display: block;
height: 0;
visibility: hidden;}            

/* ---------------------------------------------------- */
/* SLIDESHOW > SLIDES
/* ---------------------------------------------------- */
#slideshow .slides {
overflow: hidden;
width: 960px;}

#slideshow .slides ul {
/* total width of all slides -
960px multiplied by 3 in this case */
width: 2880px;}

#slideshow .slides li {
width: 920px;
float: left;
padding: 20px;}

#slideshow .slides h2 {
margin-top: 0;}

/* ---------------------------------------------------- */
/* SLIDESHOW > NAVIGATION
/* ---------------------------------------------------- */
#slideshow .slides-nav {
background-color: #ddd;
border-top: 2px solid #ccc;}

#slideshow .slides-nav li {
float: left;}

#slideshow .slides-nav li a {
display: block;
padding: 15px 20px;
outline: none;}

Add these styles to a slideshow.css stylesheet
in a CSS directory within the root. You should now see something
similar to this:

tabs

Step 3: Making it function without JavaScript

Some of you are probably wondering how on earth this is going to work
by now so I won’t make you wait any longer.

All we need to do is give each of our slides an ID and reference that
ID in the href attribute of the appropriate navigation item. It’s that
simple.

Your new markup should look as follows:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>Tabbed jQuery slideshow</title>
        
        <link rel="stylesheet" href="css/slideshow.css" type="text/css" media="screen" />        
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
    </head>
    <body>
        <div id="slideshow">
            <div class="slides">
                <ul>
                    <li id="slide-one">
                        <h2>Slide one</h2>
                        <p>
                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
                            Donec pretium arcu non velit. Phasellus adipiscing auctor 
                            lorem. Curabitur in urna ut purus consequat sollicitudin. 
                            Phasellus ut diam. Cras magna libero, tempor id, venenatis 
                            sit amet, venenatis et, dui.
                        </p>
                    </li>
                    <li id="slide-two">
                        <h2>Slide two</h2>
                        <p>
                            Nam ac nibh sit amet augue ultricies sagittis. Donec sit 
                            amet nunc. Vivamus lacinia, nisi ac tincidunt commodo, purus 
                            nisi condimentum urna, sit amet molestie odio dolor non lectus. 
                            Cum sociis natoque penatibus et magnis dis parturient montes, 
                            nascetur ridiculus mus.
                        </p>
                    </li>   
                    <li id="slide-three">
                        <h2>Slide three</h2>
                        <p>
                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
                            Suspendisse adipiscing dui a nibh. Integer tristique lorem 
                            vitae massa. Etiam dapibus, eros sit amet euismod semper, 
                            felis erat congue lacus, sed aliquam metus libero sed elit.
                        </p>
                    </li>                
                </ul>
            </div>
            <ul class="slides-nav">
                <li><a href="#slide-one">Slide one</a></li>
                <li><a href="#slide-two">Slide two</a></li>
                <li><a href="#slide-three">Slide three</a></li>
            </ul>
        </div>
    </body>
</html>         

Now test out your new code by clicking each tab… How cool is that?

This is by no means an undiscovered technique. People are already using
it on sites you have probably used without realising, such as the
Coda website.


Step 4: Adding Some Animation

Right well, that was fun! Now it’s time to add some funky sliding animations
to our slideshow.

You’ll need to download the
minified
jQuery Cycle plugin
that includes all transitions and save it as jquery.cycle.js
within a ‘js’ directory in your project root. Then add the following to your
<head> below the jquery library script tag.

<script type="text/javascript" src="js/jquery.cycle.js"></script>
<script type="text/javascript" src="js/slideshow.js"></script>

We’ll now create the slideshow.js file mentioned above and save it in the
‘js’ directory with the following code:

$slideshow = {
    context: false,
    tabs: false,
    timeout: 1000,      // time before next slide appears (in ms)
    slideSpeed: 1000,   // time it takes to slide in each slide (in ms)
    tabSpeed: 300,      // time it takes to slide in each slide (in ms) when clicking through tabs
    fx: 'scrollLeft',   // the slide effect to use
    
    init: function() {
        // set the context to help speed up selectors/improve performance
        this.context = $('#slideshow');
        
        // set tabs to current hard coded navigation items
        this.tabs = $('ul.slides-nav li', this.context);
        
        // remove hard coded navigation items from DOM 
        // because they aren't hooked up to jQuery cycle
        this.tabs.remove();
        
        // prepare slideshow and jQuery cycle tabs
        this.prepareSlideshow();
    },
    
    prepareSlideshow: function() {
        // initialise the jquery cycle plugin -
        // for information on the options set below go to: 
        // http://malsup.com/jquery/cycle/options.html
        $("div.slides > ul", $slideshow.context).cycle({
            fx: $slideshow.fx,
            timeout: $slideshow.timeout,
            speed: $slideshow.slideSpeed,
            fastOnEvent: $slideshow.tabSpeed,
            pager: $("ul.slides-nav", $slideshow.context),
            pagerAnchorBuilder: $slideshow.prepareTabs,
            before: $slideshow.activateTab,
            pauseOnPagerHover: true,
            pause: true
        });            
    },
    
    prepareTabs: function(i, slide) {
        // return markup from hardcoded tabs for use as jQuery cycle tabs
        // (attaches necessary jQuery cycle events to tabs)
        return $slideshow.tabs.eq(i);
    },

    activateTab: function(currentSlide, nextSlide) {
        // get the active tab
        var activeTab = $('a[href="#' + nextSlide.id + '"]', $slideshow.context);
        
        // if there is an active tab
        if(activeTab.length) {
            // remove active styling from all other tabs
            $slideshow.tabs.removeClass('on');
            
            // add active styling to active button
            activeTab.parent().addClass('on');
        }            
    }            
};
$(function() {
    // initialise the slideshow when the DOM is ready
    $slideshow.init();
});


NOTE: To keep this tutorial short, I won’t explain everything
in this new javascript file but if you have any questions, feel free
to ask in the comments below and I’ll do my best help you out =)

Open your updated slideshow in a browser (ensuring there is no #slide-{num}) on
the end of your URL) and wait… See it sliding?…
Great! Now you can click the tabs and watch it slide a little quicker.


Step 5: Highlighting the active tab

So, we’ve got it working but what’s this $slideshow.activateTab()
method that we added? Well it isn’t entirely necessary since the jQuery Cycle
plugin already adds an .activeSlide class to the active navigation
link for you, however, I like to give a little more control over my navigations so
this method just adds an .on class to the parent <li>
of the active link.

With this in place, you can add the following CSS to the end of our
slideshow.css stylesheet to highlight the active tab:

#slideshow .slides-nav li.on,
#slideshow .slides-nav li.on a {
background-color: #eee;}

#slideshow .slides-nav li.on a {
position: relative;
top: -4px;}

When you preview, you’ll probably notice that the first tab isn’t highlighted on
page load…this is easy to fix…just use jQuery to add a .js
class to the <body> tag as shown below:

$(function() {
    // add a 'js' class to the body
    $('body').addClass('js');
    
    // initialise the slideshow when the DOM is ready
    $slideshow.init();
});    

Then prepend the CSS we just added with the new .js class:

.js #slideshow .slides-nav li.on,
.js #slideshow .slides-nav li.on a {
background-color: #eee;}

.js #slideshow .slides-nav li.on a {
position: relative;
top: -4px;}

This means the highlighted buttons will only be styled if the user has javascript
enabled and then we hard code the .on class for the first tab in
the slideshow navigation:

<ul class="slides-nav">
    <li class="on"><a href="#slide-one">Slide one</a></li>
    <li><a href="#slide-two">Slide two</a></li>
    <li><a href="#slide-three">Slide three</a></li>
</ul>

…and voila! Try disabling/enabling JavaScript and refreshing the
slideshow to make sure everything still works and we’re done!

Javascript Off
Final Product


Tags: jQuery
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Tonny

    The jquery.cycle.js that you download DOES NOT WORK, copy the jquery.cycle.js that is used on the DEMO, that one WORKS

  • Neue71

    Great tutorial, however, when I try to have more than one sample (so several scrolling “movies”) on one single page, then it stops working. Any way around that?

  • Kirk Docker

    Hello, great tutorial!

    Is it possible to have the nav buttons outside of the #slideshow div?

    Thanks

  • http://blog.silverdoves.com silverdoves

    Thanks for this great tutorial! It’s also great to see other girls out there in the field providing such great resources!

    I am having trouble displaying images in my slides. They show fine in Firefox and IE but not Chrome or Opera. I have tried some of the fixes I read in the comments but I am either having trouble implementing them correctly or they just aren’t working for me.

    Can someone provide a clear or perhaps more detailed explanation about how to make this work? Thank you!

  • brian

    Great tutorial with clean code that degrades gracefully. I will be using this in my next project(s). Much appreciated! Net Tuts is a great resource.

  • Kim

    Hi,
    I’m trying to use this tutorial and I think it’s great.. but I’ve come up with some issues that I was hoping you could help me with.

    I’m trying to use this image gallery for both vertical and horizontal images. I’ve noticed that there’s always a huge gap underneath all the horizontal images as it’s making room for the vertical images. Also, all of the vertical images look weird as they’re not aligned in the center because of the room that needs to be made for the horizontal images.

    I’m wondering if there’s a way to change this? Here is what I mean
    http://www.kahwebsitedesign.com.au/Newfolder/product.php

    • Raj

      Hi Kim, you can do the same by just changing:

      fx: ‘scrollLeft’, // the slide effect to use

      to

      fx: ‘fade’, // the slide effect to use

      in ‘slideshow.js’ file (7th line)

      Hope this helps.

      Thx
      Raj

  • Stuart

    Hi all.

    I have been trying to accomplish the same thing as Pat from September’s comment.
    I need to make an image for next & an image for prev work with this slideshow. I have everything else up and running but not this one crucial part for my site.

    Please can someone help?
    I know very little about code so please explain in what you would consider “Too much detail”.

  • http://www.hiccupsolutions.com Saurabh

    Hello This is superb..

  • http://www.thisoldbear.com Daniel Williams

    An Opera Fix I found works is giving the same height values to:

    #slideshow .slides
    #slideshow .slides ul
    #slideshow .slides li

  • http://www.rinnku.com Nathan

    This is excellent – I love how it degrades so gracefully.

    Look out for this on the homepage of http://www.rinnku.com soon!

  • http://www.creativealys.com Creative Alys

    Its the one for which I was searching out. Thanks a bunch (Y)

  • Stuart

    Hi all.

    Can anyone help me with my question from the 10th Feb regarding next and prev buttons? There was a post earlier but I didn’t understand the later stages about adding stuff to the HTML. can anyone help, I’m really stuck??

    • http://www.dietmarhartje.de Dietmar

      Hi, just delete the “Next” in Prev and the “Prev” in Next. Than open up the css-file where you define the slider styles and add this (vary the dimensions and the image-source):

      a#next, a#prev {
      display: block;
      width: 33px;
      height: 100px;
      background: url(../images/yourimage.jpg) no-repeat;
      outline: none;
      }

      This is not tested and I hope it works.

      Cheers!

      • Stuart

        Dietmar, Thank you so much for replying this is driving me nuts.
        Unfortunately I don’t understand the first part of your reply. I have images labels 1, 2, 3 etc etc that you can click to forward the slide to whichever slide you choose be it 1, 2 or 3…. But I cannot work out how to do a next or previous button? Where does it say the “Next” that I’m supposed to delete or the “Prev”?? The css part I understand I think but not the first bit. Please help if you can, step by step….
        Many thanks in advance.

      • Stuart

        Still having no luck with this. should I try bxSlider instead? I liked the functionality of this slider but with no next or prev buttons I can’t use it………..Can anyone help? Is anyone else having this problem?

  • http://www.dietmarhartje.de Dietmar

    Hi, thanx for this great tutorial. It’s perfect to get a sleek slider inside the website without loading tons of scripts and css files.
    Is it possible to extend the tabs with the jquery carousel script? Any help would be very welcome!!!

    Cheers

  • http://www.rahjv4.tk cebuano programmer

    thanks for this! .. . . . .

  • Maria

    Love the tutorial, thanks!

    I’ve added images to fade in and out along with the text. I am having trouble with the .js slideshow background color though. My html page has a dark background split in two. When js is disabled, the view of the page is perfect; however, once I activate the js a white left and bottom edge appear with the slides. I’ve tried changing the Slideshow background color attribute to transparent but when i preview the file in IE, I still get those white borders (even though I’ve set all borders to 0px). If I change the color however, it works fine, but because of my split background it just doesn’t fit right.

    I even tried adding the Important: see below:

    #slideshow {
    width: 820px;
    height: 316px;
    border: 0px;
    background-color: transparent!important;}

    Is there something I need to change in the actual .js files in order to make that white border dissappear?

  • Kenneth Traub

    I am running into a very similar issue to what Maria has with IE. Is there a fix for this?

  • Damian Hope

    You can fix the ie problem with “cleartypeNoBg: false, // set to true to disable extra cleartype fixing (leave false to force background color setting on slides)” this will fix the annoying background colour.

  • Amy

    Is there a fix for getting this to work with jquery-1.4.4.min.js? I have another script that requires I use that version or later and this slideshow seems to break with that version or later.

  • Lisa

    Wow, thank you so much for sharing this code. I am making many mods on it now and you helped explain code so well. You helped save my job!

  • Krista

    Hey,

    Thanks for the tutorial. I’ve got everything working except I am trying to implement a pause button rather than a pause on rollover. I don’t know much about syntax so as much detail you can post would be appreciated. I’ve been toying with

    $(“button”).click(function() {
    $(‘slideshow’).cycle(‘pause’);

    but can’t get it to work. Any advice? Thanks.

    • Tuan

      Hello Krista,
      Did you or anyone got a pause button working ?
      Help would be great!
      Rest is working smoothly.. tks

  • Jasmond

    ” $(function() {
    // add a ‘js’ class to the body
    $(‘body’).addClass(‘js’);

    // initialise the slideshow when the DOM is ready
    $slideshow.init();
    }); ”

    where should i paste this code?

    Please advice.
    Thanks

    • http://www.hao.ucar.edu/ Wendy

      ” $(function() {
      // add a ‘js’ class to the body
      $(‘body’).addClass(‘js’);

      // initialise the slideshow when the DOM is ready
      $slideshow.init();
      }); ”

      I am also wondering where to paste this code?

      Please advice.
      Thanks

  • http://www.3ds.com.gr/fotovoltaika.html fotovoltaika

    May i change the

    to a newer version??
    I have a compability problem..

  • JP

    Awesome tutorial. Thank you very much!

    I was looking for a slider that could slide two divs side by side. I actually modified it to work on Ning network for a client of mine. They wanted to slide 468×60 banners, two at a time.

    I was able to build this to suite what I needed and everything went off without a hitch. I was able to make the changes and have it all uploaded on my clients site in less than 30 minutes.

    Would you like me to post credit back to you Jenna on my personal site?

  • ian

    how to minimize the height where the links are shown?

  • ian

    thanks by the way

  • ian

    please help me. is it ok to delete this script?

  • http://www.facebook.com/emmachinedu EmmaChinedu

    Wow…very interesting…it worked perfectly fine. Thanks for the share

  • http://ajaxexamples.org J.B.

    I’m a newbie to jQuery.

    Supposing you add a trigger button something like

    <input value="Enable Slideshow" onclick="”>

    How can you trigger the slideshow to start?

    The reason for my asking is that Facebook welcome page disallow autoplay so I need some kind of trigger to allow a user to enable it.

  • http://facebook.com/christopherrdowns Christopher

    Madam, simply divine. :) thank you for taking care of something that I had two clients asking me to do. Your help has been the best part of my coding day.

    God bless
    Christopher

  • http://www.sss.com MSR

    Great…!

  • http://divinedesigns1.net Travis Trotman

    Hi, i edit the slideshow to my liking, and i use images instead of words, the problem im having is getting the images to center in the slideslow, how do i center these images?

  • http://divinedesigns1.net Travis Trotman

    nevermind i got it in the center 0.o wat i did was an an align to the tag and for where it says Slide 1 above the word/image i did the same in the tag 0.o thanks a lot it was an awwsum tuts now i know how to do it for both image and word

    0.o still workin on the image part tho but thanks

  • El.a

    Hi, this is truly great.
    Can you advise me on how to insert this into an existing page?

  • Laurie

    Could this be amended to just auto scroll, without the tabs? And if so, how?

  • http://www.mechat.co.id Me-Chat

    nice your article…….:D
    please……feature list

    and visit me

  • http://www.davalign.com Dave

    Very nice tutorial. I was looking through comments but didn’t see an answer to my question: can you stop the sliding once someone clicks on the tab? Right now, it jumps to the appropriate slide when tab link is clicked, but starts scrolling again shortly thereafter.

    • Wesley

      Did you ever find the answer to this? We want to do the same thing.

  • sam

    for highlighting on the first tab, why go through all the trouble of a new style and new bit of javascript in the html. I put this line just before the init in slideshow.js:

    $(‘.slides-nav li:nth-child(1)’).addClass(‘on’);

    if javascript is on, it will add the ‘on’ class to the first item when the page loads, if it’s not, it won’t.

  • kyu

    Hi,
    nice tutorial. thanks. I have a question. Is it possible to start with the second li of the slides?
    Best regards.

  • Yousef Amiri

    Thanks a lot.

  • Amberley

    Hello there,

    I’m unsure if you’re still answering questions for this but I have a problem, surprise surprise.

    I’m not sure why, but the slide is completely messed up when I turn JavaScript off.
    I’ve not put it up on my site yet as I want to to work properly first. However, I have put up a testing page with the slideshow on it so you can see what happens…

    http://testingmeters.co.uk/TEST/TESTING%20PAGE.html

    I’ve adjusted the coding quite a bit so there’s something I’ve changed that has stopped it from working with JavaScript off, but I don’t know what.

    This has been bugging me for weeks, Is there anyway you could take a look at it for me and help me figure out where I’ve gone wrong?

    Many thanks.

  • http://www.levitijerina.com Levi Tijerina

    Hey All,

    Like Amber before me, I’m not sure if people still check this, but I’m having some issues with visibility. The code worked out perfect for me…in Chrome. In Chrome, everything looks great on my browser, but when I open it up in Safari, IE, or Firefox, nothing comes out. Is there something that I coded wrong, because I’m assuming that’s what I messed up on.

  • chris

    Hi,

    is there a possiblity to add submenus that are only shown on mouseover?

    Best regards.

  • Dutchmaster

    Hi there,

    I just used this code and changed everything to my likings..
    but now the timeout or FX doesnt work?

    it looks like the slideshow.js isnt loaded cause if i delete this file.. it doenst make any changes to my slideshow..

    i got this linked in my head:

    what i basically want is to set the timeout

  • Dutchmaster

    NVM :) i fixed it :P Thnx

  • http://MSiddharth Siddharth

    Awesome !!! Sexy !!! Fab

  • gopikrishna

    Hi, your tutorial is too good. But I want to scroll the content vertically. where should I change the code.

    Thanks,

    • Steve

      In the Javascript you are going to want to change the fx. It’s at the very top of the slideshow.js file

      Instead of

      $slideshow = {
      fx: ‘scrollLeft’,
      }

      you should change it to either

      fx: ‘scrollUp’,
      –OR–
      fx: ‘scrollDown’,

      Hope this helps!

  • Joel

    when I try to change the animation effect from ‘scrollRight’ to ‘fade’, nothing happens.

    Any ideas why this would be?

    How can I use alternate transition effects?

  • Tayssir

    hello dear i really like this tutorial
    but can you tell me how can i use two auto scrolling slideshow in same page ?

  • http://www.tradeport.com.ph/blupass WEBDY

    nice tutorial kip it up!:)

  • matteo

    I’ve changed the code a bit to have just images scrolling with no links or text and I experienced some problems on Safari and Chrome…the images where not showing..at least not all of them…I was able to see only the first part of the slideshow (the first top 20px or so)…I fixed it changing this:

    #slideshow ul {
    margin: 0;
    padding: 0;
    list-style-type: none;
    height: 1%; /* IE fix */}

    to this:

    #slideshow ul {
    margin: 0;
    padding: 0;
    list-style-type: none;
    height: 1%; /* IE fix */
    height: 200px; /* height of the images I used for the slideshow */}

    Hope this can help!

    Matteo