Building a Simple jQuery Rotating Carousel

jQuery Carousel Content RotateThe homepage is the most valuable real estate of a web site. Oftentimes, it is also the most viewed page that determines whether or not a user will explore further into the site.

One way to maximize the real estate of a homepage is to dynamically show and hide content. For example, one piece of content could feature information about a product and then automatically hide to show a new piece of content advertising some other part of the web site. Not only does this enable you to create more space where there once wasn’t, it also helps you to grab the attention of the user. Any type of animated content is almost always guaranteed to attract eyeballs.

The best way to implement something like this for your own homepage (or a subpage, it doesn’t have to be a homepage) is to implement what’s called a carousel.

The carousel automatically rotates through pre-defined featurettes, be they media or text, and allows the user to manipulate which content is shown via a mouse hover or click event.

The Example

Let’s take a look at a quick example: http://www.clecompte.com/examples/carousel/

This is a bare bones carousel that can always be beefed up with design elements later on. As you can see, it’s automatically rotating through three content pieces. If you hover your mouse over any of the three content titles to the left, the animation will end. You can then continue to navigate to the other pieces of content by hovering over the other titles.

Why does it behave like this? It begins with the automatic animation to make sure all of the content gets play in case the user doesn’t interact with it. It ceases the animation once the user interacts with it so that it doesn’t animate as the user is trying to read the content.

How it Works

So how does it work? Below is the full source code of the CSS and jQuery.

The CSS

The CSS is pretty straightforward. The left side navigation of the three content pieces is setup using an unordered list while the content is housed using a div container. All of the content containers must be hidden as the jQuery will initialize everything.

body {font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;}

.feature_nav {width:200px; float:left;}
ul {list-style:none; margin:0; padding:0;}
ul li a {background:#666; color:#fff; padding:8px; border-width:1px 0 1px 1px; border-color:ccc; border-style:solid; display:block; font-size:14px; font-weight:bold; margin:0 1px 2px 0; text-decoration:none;}
ul li a.on {background:#ccc; font-size:16px; color:#333; border:none; margin-right:0;}

.feature_content {width:460px; float:left; height:160px; background:#eee; border:2px solid #ccc; padding:20px;}

#feature_one, #feature_two, #feature_three {display:none;}

h1 {color:#333; font-size:22px; border-bottom:2px solid #fff; margin-top:0;}

The jQuery

Here comes the fun part. Below is the full source of the jQuery which I’ll explain in a moment.

$(document).ready(function() {

  /* HOME ANIMATION */
  function contentRotate(feature) {
    if (doAnimate) {
      feature.fadeOut("fast", function (feature) {
        return function () {
          $(".feature_content div").hide();

          /* HIGHLIGHT RELEVANT CONTROL */
          if ($(this).attr("id") == "feature_one") {
            $(".feature_nav .on").removeClass("on");
            $(".home_one").addClass("on");
          }
          else if ($(this).attr("id") == "feature_two") {
            $(".feature_nav .on").removeClass("on");
            $(".home_two").addClass("on");
          }
          else if ($(this).attr("id") == "feature_three") {
            $(".feature_nav .on").removeClass("on");
            $(".home_three").addClass("on");
          }

          /* FADE IN NEXT ITEM OR GO BACK TO FIRST */
          feature.fadeIn("fast", function () {
            if ($(this).attr("id") == "feature_three") {
              setTimeout(function () {
                contentRotate($(".feature_content div:first"));
              }, 4000);
            }
            else {
              setTimeout(function () {
                contentRotate($(feature.next()));
              }, 4000);
            }
          });
        };
      }(feature));
    }
  }

  /* HOME FEATURES */
  $(".feature_nav a").hover(function() {
    var current = $(this).attr("title");
    $(".feature_nav .on").removeClass("on");
    $(this).addClass("on");
  });

  $(".feature_nav a").click(function() {
    return false;
  });

  var doAnimate = true;

  contentRotate($(".feature_content div:first"));

  $(".home_one").hover(function() {
    $("#feature_one").fadeIn();
    $("#feature_two").hide();
    $("#feature_three").hide();
    doAnimate = false;
  });
  $(".home_two").hover(function() {
    $("#feature_one").hide();
    $("#feature_two").fadeIn();
    $("#feature_three").hide();
    doAnimate = false;
  });
  $(".home_three").hover(function() {
    $("#feature_one").hide();
    $("#feature_two").hide();
    $("#feature_three").fadeIn();
    doAnimate = false;
  });

});

The easiest way to explain this code is to start from the bottom. A variable called doAnimate is created to determine whether or not the animation should run. It is initially set to true so that the content will rotate when the page loads. Calling the contentRotate function, which I’ll get into shortly, initializes the content rotation.

The only way the animation can be stopped is if the user hovers over the left side titles. That’s what the three hover functions are doing. For example, if the user hovers their mouse over the second title, the first and third containers will be immediately hidden if they are visible, the second container will be shown, and the doAnimate variable will be set to false to end the animation.

Above those three functions is the contentRotate function call that I mentioned earlier. When this function is called, the first div container within the container that has class “feature_content” is passed. So, if you refresh the page, the animation will always begin with the first content feature.

In the actual contentRotate function itself, the function will only run if doAnimate is true, which it is by default. After that you see a function to fade out the current content container, which is done after the contentRotate function is given the next content container. The hiding of all divs inside the “feature_content” container may seem counterintuitive, but this is done to prevent any of the content containers from appearing prematurely.

The area in the contentRotate function with the comment about highlighting the relevant control is what determines which left side title will be highlighted. This is accomplished using a simple if statement. If the current visible content container has an id that matches its associated title, then all the other titles are deemphasized and only the associated title is highlighted.

The next part of the contentRotate function is where the magic happens. The current content container is faded in and an if statement is immediately run to make sure the last content container has not been reached. If the last container has been reached, the if statement will go through the function again starting with the first container. If the last container has not been reached then the function will continue with the next container in sequence. All of this is set to a 4-second timer.

So there you have it: a simple carousel feature that is flexibly built using HTML, CSS and jQuery. This is just a prototype, so if you find problems or areas of improvement, feel free to drop a comment.

8 Responses to “Building a Simple jQuery Rotating Carousel” (Leave a Comment)


  1. ind says:

    Hi, the carousel doesn’t show the divs I put inside #feature_one or #feature_2 divs, they have a display:none. I managed to make them fade in on the mouse over, but they won’t rotate together with the #feature divs. Is there any way I could make that work? thanks!!

  2. no says:

    Simple, nicely done.

  3. richard says:

    I’ve noticed a bug in this script where if the buttons are mouseover’d too quickly then the current div doesn’t fade out, and the next div fades in below and gets stuck.

    Any idea what’s causing this and how I can fix it? I’ve had a little play with the CSS and the .js but can’t figure it out.

  4. richard says:

    I figured out a simple CSS fix; house the whole thing in another div with your desired dimensions, and set overflow to hidden.

    I also played with setting the z-index of feature_content div to 100, and all content below feature_content to 200. This is a messy hack though that could easily be broken by other scripts.

    All in all, a very nice simple script. Cheers!

  5. fran2tek says:

    Very good simple text rotator.
    I use it to rotate tweets from twitter with a nice
    custom css style. Work fine !!!

  6. jim says:

    Anyone have any idea why the rollovers don’t seem to work in Joomla? (ie-when you roll over the navigation boxes the appropriate content doesn’t come up. It just keeps cycling through the order of the content.)

  7. JDMorris says:

    I’m wondering if there is a way to make the animation stop when the cursor is over the content and restart when the cursor moves away?

What Do You Think?