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


Add Comment

Discussion 266 Comments

Comment Page 3 of 5 1 2 3 4 5
  1. Jason says:

    For a partial fix to make the scrolling function in Opera without JavaScript, add this Opera filter to your CSS:
    @media all and (-webkit-min-device-pixel-ratio:10000),
    not all and (-webkit-min-device-pixel-ratio:0) {
    #slideshow .slides {overflow-x:scroll;}
    }

    This will allow Opera users to still access the slides without JavaScript. Unfortunately, it adds an ugly scrollbar, but depending on your design, this could be hidden by layering an element over the scrollbar.

  2. Joe says:

    I love the smooth transitions.

  3. Marcel says:

    FYI, to make my navigation show up, I had to copy and paste the non-minified version of Cycle from the demo page: http://nettuts.s3.amazonaws.com/325_tabbed/demo/js/jquery.cycle.js

    Might want to clarify this under Step 4?

  4. Petsen says:

    hm… seems like it doesn’t like PHP files… the source files work just fine on FF3.5 but the same content inside a PHP file doesn’t.. weird.

    P.S.
    Very nice tutorial!

  5. gp sidhu says:

    hi mam thanks for this wonderful tututorial
    now what i am trying to do is integrating this in another web page but when i test on the local server it works fine but does not work when uploaded to the server
    please help!!!

  6. David Moreen says:

    Jenna, thank you for this great tutorial. One thing that every designer needs to bare in mind while making a project with javascript is that everyone will not have javascript turned on, so the site still needs to function well. Something similar to this will be included in every website that I construct from now on.

  7. Joe says:

    First off, thanks so much for supplying the info and code for this application! Quick question, how customizable is it? Would it be possible to switch the orientation of the layout so it displayed vertically?

    Basically, what I would like to do with it is have the links on the right side and have the information display to the left of the links. Similar to the main news section here: http://ca.msn.com/ at the top left under the nav bar, but have the links on the right and the info on the left.

    Would it just require some tweaks to the css or is this not possible?

  8. Any chance somebody could help me with an issue I am having with this tutorial?

    I have this running but the problem is I have a search suggest form in the search bar and there is a conflict which means I am not able to select products.

    I think it is a CSS problem but am not sure how to fix it! Any help would really be appreciated.

  9. Frog says:

    Thanks Jenna, finally an auto play content slider that’s simple enough to edit and skin :)

  10. Trivial says:

    Thx? Jesus you lonely fools only interested in Jenna. Its a JQUERY slider…
    “WHOA!!”.

    Common and its not truly active either cuz it takes a click event instead of calculating the clientX mouse pos over the parent. Chicks play video games too. I’m not gonna build a statue cuz one wins a game. Girls can’t use JQUERY?

    Not to take away from the “MAJOR ACCOMPLISHMENT” but if Jenna were fat and ugly you retards wouldn’t be stepping on yourselves to say: Great Job Jenna!!

    Did she invent bread or something? Trivial. It wasn’t bad, but it shouldnt be noted only cuz she a chick. I make math models in JS and 3D parallax, rotating, true active scrolling, etc..UIs.

    Anybody wanna write me a freakin poem? I’m HOT!!! Take my word for it. :)

    Ill put up a Brad Pitt pic to make my code cooler more impressive too.

    “Oh Wow Brad, so kool to see an actor that can blog an code. Your code is so awesome!!!

    • Jenna says:
      Author

      Wow… lol.

      Exactly, it’s not complicated at all, that’s the beauty of it. However, not many people were aware that it could be done which is why they’re so grateful I guess.

      Now go throw your toys out your pram somewhere else and send me one of your Brad Pitt pics while you’re at it ;)

  11. Trivial says:

    And half your Gravatar Pics look like “nerd glamour shots” gone horribly wrong. I’m taking a shower after I post this. Poor Jenna.

  12. S. Fox says:

    Great tut. One question: I’m trying to have the slideshow content resize when the browser window is resized.

    I changed the #slideshow to 100% but that only resizes the slideshow container but not the text within. So in other words, if I open a window 800×600 then resize to 1024, the content doesn’t resize accordingly. If i reload page, the content then resizes to fit container.

    Does anyone know how I can force the slideshow content to resize when the browser window changes? Thanks.

  13. perfect tutorial! I’ve been searching for this exact tutorial… I stumbled across it a bit back and forgot to bookmark it.. thanks for the post!

  14. Alfok says:

    Hi, great Job!!, it works perfectly in Firefox and IE6, but I’ve looking for something like this http://spaceforaname.com/filmstrip.html …thank you btw

  15. Kreativo says:

    Great tutorial and great idea of course, but i was wondering how would you do if you use for example 3 different pages with their own contens so each of them have a different height

  16. Hmmm, maybe a little too difficult for me, but I think I’ll try:)

  17. helmut says:

    can anybody help me?
    my slideshow doesnt work in ff :-(

    but only because of any combination with an other DIV i think…
    on this page it works: http://www.charivari.de/home_slide1.php

    has anybody an idea? thank you!

  18. Nathan says:

    Excellent, love your work and your attitude to ‘things that can’t be done’!!!

  19. Markaid says:

    excellent and useful effect thanks

  20. Mauricio says:

    Very nice and helpful work! Thank you for the tutorial and the code.

    What about if I replace the content text for images and I want those images have links to more info outside the slideshow or inside pages? can that be possible to do and how? can be the nav-buttons link too? :~

  21. dracon says:

    Hi Jenna,

    i found your tut because i was looking for help for Safari on Windows. The hole code of you did i find in a Joomla module. So i came on your tut and thoght all this code looks like the code in the module. Yes it is a hole copy of your code with some tunes for Joomla. I startet to modify the code for my needs.
    At all I want to say THANK YOU for this fantastic tutorial. Now I understand much more :)
    Really good work!

  22. Ricardo says:

    the script is nice! but i can’t use a background-image on the background of the slide on IE, can someone help me?

  23. Ricardo says:

    problem resolved..
    just added to jQuery Cycle Plugin

    cleartype:true, cleartypeNoBg:true

  24. Romulus says:

    u r smoking….as in HOT i mean.!!!

  25. ed says:

    GREAT TUTORIAL! I was wondering if the fx: “scrollLeft” could be set to fade instead. I to would also like to have something similar to the the main news section at http://ca.msn.com/ I’m not having any trouble with the css I’m new to javascript though

  26. Danijel says:

    Hi i was wondering, how can i make this loop only once ? tnx ..

  27. oliflorence says:

    Hi,
    great tutorial.

    just wondering how to change the default slide onload. i am working on a registration, the page is on the third tab and I want to validate the form server side, so i need to redirect onto the page but with the third slide open in stead of the first.
    I know how do it with the navigation but can’t seem able to do it with the actual content area.

    Any pointer appreciated.
    many thanks

  28. CP says:

    Is there a way to have multiple scrolling slideshows on the same page? For example, Id like to feature two slideshows with different content in each.

    Any suggestions would be great.

    Thanks.

  29. Kyle says:

    This has been a great help. I just started teaching myself how to use html (or any comp language) for the first time last week by making a webpage from scratch.
    I have a problem getting it all to work though. I have the slideshow up and running, just can’t get it to auto scroll. My URL ends with #slide-one. Any ideas?

    Thanks

    • Mollie says:

      Hey Kyle, I am having the same exact problem you described above!! Any chance you’ve solved it? It’s been driving me crazy trying to figure it out!

      Thank you!!

    • mollie says:

      Hey Kyle, I was wondering if you solved this issue! I’m having the same problem and can’t figure it out! I would love some advice!

      Thank you!!!

  30. A. says:

    awesome script!! i’ve been looking for something simple like this forever! i’m using it however it’s clashing with my standard list navigation …. the navigation tabs are only clickable on the edge when i have the standard nav in the page … is there any way to fix it?

  31. aw says:

    not sure if my prev post went thru but … i tried to use this with a standard list navigation in the page but it seems to be clashing … the tab is only clickable on the very edge when you want to manually slide it … on it’s own it works great though … is there any way to fix this?

  32. Technista says:

    Thank you for explaining the process in such a straightforward, concise manner. You really demystified the process! I was able to easily configure it for my CMS.

  33. Blaise says:

    Say I wanted to put an image in instead of text how can I increase the height! Please HELP thanks! Great Tut by the way!

  34. LYKC says:

    Absolutely perfect for my needs, great slideshow! I’ve chopped and changed the CSS and used it on my homepage to showcase featured areas of my site. Check it out at http://www.lykc.co.uk Thanks again for the cool script!

  35. amko says:

    Great solution! I’m having issue with the “div.slides > ul” in the javascript. It’s pushing the dropdown for my website behind the slideshow…I need it to be above it. Any ideas?

  36. tmaan says:

    How can you get this so that instead of tabs, it’s just a “next” and “previous” button. I’ve been reading through more documentation on this and I can’t seem to figure this out.

  37. Love the transition..

    Well done.

  38. This will help us give our customers multiple options on our bookkeeping website q and A section

    A BIG Thanks

  39. Dylan Macak says:

    Hey Jenna, how would I advance the tabs on mouseover instead of click, is that possible (and easy)?

  40. Karthik says:

    Hi,
    The id value is passing at the end of URL. Can any one help me to avoid the value that is passing in URL?

  41. Rakel says:

    The first time I implemented this into a website, no problems. Since then, I’ve tried implementing this two times and it is not working right! If I open up the demo file on my computer, it works like a charm, but as soon as I copy and paste the same files into a site, even before modifying any of the styles, it doesn’t work.

    It’s applying the “on” class to the slides-nav and not removing it when it loads the next slide. Any idea why this is happening?

  42. Pat says:

    Thank you for supplying the source and showing the demo. It’s very helpful.

    I’ve been trying to add next and previous to the cycle. Is it possible to do this and still have the slides advance automatically?

    Ideally, I would want the next/prev to be separated from the tabbed nav, but if I’ve been failing miserably at that. :( Now I’m just trying to get my nav tabs to look like ( prev . slide1 . slide2 . slide3 . next ).

    Any tips?

  43. Prasad says:

    Hi I want to use same script twice in same page.

    But it not working.. pls guide me..

  44. Sebastian Andersson says:

    Do anyone now how to pause or stop the slideshow when clicking the pager link?

    Really nice slideshow BTW :D, Thanks a lot

  45. matt says:

    ok…got a weird problem…I have 4 images cycling through this script…works great on IE (which is weird in itself) but in FF and Chrome…it adds a blank slide to the end before cycling back to the beginning. any ideas?

  46. carolann says:

    Hey Jenna,

    I am having a problem getting the animation (scrolling) to work. My web administrator requires that all the files for the website be in one folder, so I have had to move the .js files to the main folder of the site. I changed the folder path on the tags for the script that goes in the head by removing “js/” before the name of the .js file.

    However, I still do not get any animation. I can click through the buttons and view the slide show, but there is no scrolling or auto scrolling.

    Can you help?

    Thanks,

    Carolann

  47. sean says:

    hey, i am wonder how to change it for photo slide?
    i am replace the text with , but it doesn’t work.
    can anybosy help me?
    Thanks.

  48. imrn says:

    Thank you for the tutorial. I am new to all of this, so this might seem like a dumb question. But how do I edit this if I don’t want it to auto-scroll? And how should I edit this if I just want it to automatically scroll through once?

Comment Page 3 of 5 1 2 3 4 5

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.