Grow your CSS skills. Land your dream job.

Start/Stop Slider

Published by Chris Coyier

A little while back I did a tutorial on a Featured Content Slider. It was neat, but a little limited in customization possibility. The two most requested features were being able to add/remove "panels" and a stop/start button.

I'm happy to say I was able to accommodate a bit with this new slider. It's not a plugin, so it's not as easy as it possibly could be, but it's much easier. There is a section at the end for customizing. The slider does feature a stop/start button and the animation goes a little farther than simply sliding to the left.

View Demo   Download Files

The HTML Markup

The markup is extremely light. Simply a wrap that contains the area and hides overflow, then a "mover" inside it to which does the sliding, then slides inside of that.

Notice there is no markup for a stop button. That doesn't belong in the markup because without JavaScript it would be useless. We'll apply that through the JavaScript. Also notice the first slide has a unique ID. We'll use that as our "test slide" to gather width information with the JavaScript.

<div id="slider">

	<div id="mover">

		<div id="slide-1" class="slide">
			<h1>Garden Rack</h1>
			<p>Donec gravida posuere arcu. Nulla facilisi. Phasellus imperdiet. Vestibulum at metus. Integer euismod. Nullam placerat rhoncus sapien. Ut euismod. Praesent libero. Morbi pellentesque libero sit amet ante. Maecenas tellus.</p>
			<a href="#"><img src="images/slide-1-image.png" alt="learn more" /></a>

		... additional slides follow format of this one, except no need for ID ... 



#slider          { background: white url(../images/slider-bg.jpg); height: 227px; overflow: hidden;
                   position: relative; margin: 50px 0; }
#mover           { width: 2880px; position: relative; }
.slide           { padding: 40px 30px; width: 900px; float: left; position: relative; }
.slide h1        { font-family: Helvetica, Sans-Serif; font-size: 30px; letter-spacing: -1px;
                   color: #ac0000; }
.slide p         { color: #999; font-size: 12px; line-height: 22px; width: 300px; }
.slide img       { position: absolute; top: 20px; left: 400px; }
#slider-stopper  { position: absolute; top: 1px; right: 20px; background: #ac0000; color: white;
                   padding: 3px 8px; font-size: 10px; text-transform: uppercase; z-index: 1000; }

Not much to talk about here, much of this is merely presentational choices. Functionally, the relative position on the #mover is important, and necessary for the sliding affect. Likewise is the absolute positioning on the img elements. With this CSS in effect, but JavaScript off, the slider will show the first slide and that's it (ideal, if you ask me).

The jQuery JavaScript

90% of what we are doing here is specific to jQuery. Makes things much easier. We'll need to make sure that library is loaded before the rest of our script.

<script type="text/javascript" src="js/jquery-1.2.6.pack.js"></script>
<script type="text/javascript" src="js/startstop-slider.js"></script>

At the top of our startstop-slider.js file, is a single self-explanitory variable

var delayLength = 4000;

Then we'll begin our manipulation, after the DOM is ready of course. The first thing we'll do is append the Stop/Start button to the slider. CSS is already in place to position and style it.

$(function() {



Next we need to get a little smart and start figuring out what we are dealing with. The number of slides and their widths are vital pieces of information for our slider. Rather than hard-code them in, we'll use jQuery to count them and determine their width. Counting is easy, width is a little more complicated as we need to pull three CSS values (width, paddingLeft, paddingRight) parse them, and add them together.

var $slide1 = $("#slide-1");

var panelWidth = $slide1.css("width");
var panelPaddingLeft = $slide1.css("paddingLeft");
var panelPaddingRight = $slide1.css("paddingRight");

panelWidth = parseFloat(panelWidth, 10);
panelPaddingLeft = parseFloat(panelPaddingLeft, 10);
panelPaddingRight = parseFloat(panelPaddingRight, 10);

panelWidth = panelWidth + panelPaddingLeft + panelPaddingRight;
var numPanels = $(".slide").length;
var tooFar = -(panelWidth * numPanels);

Now we need to write code to handle the sliding action. There are two places we will potentially want to kick off the animation. One is right when the page is loaded, and the other is when the "Start" button is pressed. Because of these two different places, it makes sense to wrap our animation in a function and call it as necessary (DRY: Don't Repeat Yourself).

function doMove(panelWidth, tooFar) {
	var leftValue = $("#mover").css("left");
	// Fix for IE
	if (leftValue == "auto") { leftValue = 0; };
	var movement = parseFloat(leftValue, 10) - panelWidth;
	if (movement == tooFar) {
		$(".slide img").animate({
			"top": -200
		}, function() {
				"left": 0
			}, function() {
				$(".slide img").animate({
					"top": 20
	else {
		$(".slide img").animate({
			"top": -200
		}, function() {
				"left": movement
			}, function() {
				$(".slide img").animate({
					"top": 20

In plain English: Check and see where the slider is. If it's at the last panel, move back to the first panel. Otherwise, move ahead one panel length. Notice all the nesting of the .animate() functions. The animate function has a callback event, which gets run when the animation is complete. So in order to have our animations run one-after-another (instead of all-at-once), we use the callbacks. So now it animates the image up, the mover over, and then the image back down, in that order.

Note that we pass in the width and "tooFar" variables, as the function needs though and they are not global variables. Also there is a little fix for IE that Eric Wendelin fixed for me, where the left value gets bizarrely set back to "auto" instead of "0".

The "Auto Play"

JavaScript provides the perfect built-in function for an "auto-playing" widget like ours: SetInterval(); We'll use it to call our function:

sliderIntervalID = setInterval(function(){
	doMove(panelWidth, tooFar);
}, delayLength);

The "sliderIntervalID" variable isn't required, but that allows us to later call clearInterval() with that ID in order to stop it. Vital for our desired functionality.

All that is left now, is to code the stopping and starting with our little button:

	if ($(this).text() == "Stop") {
	else {
		sliderIntervalID = setInterval(function(){
			doMove(panelWidth, tooFar);
		}, delayLength);

The button starts out saying "Stop", since we fired off the animation right when the page loads. That makes sense. So when that button is clicked, it checks and sees if that text stays "Stop", if it does, it stops the Interval that is running and changes the text to "Start". Magic.

If the button is clicked and it says anthing other than "Stop" (like it does when it says "Start"), the button will fire off the setInterval function again and change the button text back to "Stop". Simple and beautiful.

How To Customize

To add another panel, add another div inside the #mover:

<div class="slide">
   <h1>Name of Slide</h1>

That's it! The code is smart enough to pick it up and know what to do. You may even change around the CSS and it should survive.


  1. Permalink to comment#

    Nice! Great work, Chris. You are mojoin’ it.

  2. Permalink to comment#

    Very nice Chris! Could you get the ‘numPanels’ variable using size(); to count the number of panels automatically?

    What happened to Intense Debate? Not working out?

  3. Great post! Lucky for use you hit publish early!

  4. Chris Barnett
    Permalink to comment#

    Another great one. Not just to find a way of putting it to use.. Cheers!

  5. Thanks all =)

    @Toby: Good idea, definitely could count the panels that way, and probably measure the size too.

    I’m still syncing to intense debate for now, but I’m gonna wait and see if they can resolve some of my syncing issues and some other stuff before I go back to full system. I really like most of it, probably will resume at a future date.

  6. Man! I have a post just like this set to go live tomorrow! I’ll leave it till next week or something.

    Nice work Chris, always a pleasure.

  7. jamie
    Permalink to comment#

    Very nice Chris. I really like this one. I plan on using it very soon. Keep up the good work.

  8. fantastic! this is going to work great on an update I’m doing for my companies website. Thanks so much for sharing.

  9. Permalink to comment#

    I think the 2nd paragraph under “HTML Markup” should be…

    “Notice there is no markup for a stop button. That doesn’t belong in the markup because withOUT JavaScript it would be useless. We’ll apply that through the JavaScript.”

  10. Permalink to comment#

    On another note… THANKS. I’ve been going thru the daily Jquery screencasts on themeforest and this helps for a real application of what I’ve been learning.

  11. Permalink to comment#

    wow awesome!!!!!!! thanks

  12. Bert
    Permalink to comment#

    Simply beautifull.

  13. Permalink to comment#

    Nice sharing thank you

  14. Chris-

    Not sure if you were aware or not but this doesn’t work in IE7.

    When you load the page the image slides up right before the whole slide is supposed to move, and then I get an “Error on page”. Looks to me like a possible JS error.

    Anyways, not sure if you knew this already and/or if you care to support IE.

  15. This is beautiful – very nice work. Can’t wait to see the updates you bring to this in the next version!

  16. @Kyle – Thanks for pointing that out. I’m seeing the exact same thing. I have no clue why.

    If anyone is great at this cross-browser JavaScript debugging stuff, please lend a hand =)

  17. Permalink to comment#

    Great work, this is a good example of how javascript and css can be integrated in order to produce some very professional looking results. Plug some pictures and content into a database, pull from it, and you have a pretty fancy news-rotator sans-flash (very handy).

    This little snippet works flawlessly on Firefox 3.0 and on Google Chrome 0.4.1, but it seems to have a few issues in IE (not surprising at all since IE is pure garbage). In IE6, the panels do not stay contained (all 3 of them are displayed side-by-side). In IE7, the script runs the first panel, and then freezes after that.

    My guess is that some IE specific ‘hacks’ will need to be formatted out through the css/javascript in order to get IE to behave properly. If I have some time this afternoon I’ll play around and see if I can contribute to fixing the IE problem.

  18. Yo Chris if you replace the jQuery packed version with the unpacked one I’ll fix this for you. It’s a bit painful to debug the packed version.

  19. Done. I threw the development version up there for now.

  20. Permalink to comment#

    Hi Chris – Noticed the same thing with IE 7. From your last post, it looks like you’ve fixed this, but the date stamps on the downloads are still 12/4. Is the development version available elsewhere? In IE 7.0, is NaN

    Thanks for this elegant code.

  21. Here’s the fix:
    Add if (leftValue == “auto”) { leftValue = 0; }
    Just after
    var leftValue = $(“#mover”).css(“left”);

    This is because leftValue is “auto” in IE.

  22. Perfect! Thanks Eric.

    I updated the code and the download. I’ll update the article in a little bit.

  23. Permalink to comment#


  24. Dan
    Permalink to comment#

    Fantasic write-up, Chris!

    One thing, I don’t think you’re closing the page-wrap div.

    Good stuff…

  25. Donna Cruz
    Permalink to comment#

    Hey Chris, I always enjoy your articles. Do you have a sample that works with javascript turned off for us that have to deal with Educational/Government sites?

  26. @Dan – I’ll fix that in the update I’m gonna do in a few minutes here, thanks.

    @Donna – It does work with JS off, just displays the first panel only. That’s about the best that’s gonna happen with JS off.

  27. @Chris – thanks for such a timely response in fixing the code. This is going to work great now that I can use it in IE. You rock.

  28. You are great chris, I was searching for such article ..

    Many Thanks

  29. Looks quite swell! Keep ‘em coming.

  30. So great looking slider! Thanks a lot, lovely!!!

  31. Permalink to comment#

    Thanks to Chris for such an awesome article and to Eric Wendelin for fix the IE bug. Win Win, iLove it… keep up the good work!

  32. Sebastian
    Permalink to comment#

    absolutely gorgeous. nice work chris.

  33. Permalink to comment#

    Yeah ! Nice demo

  34. Permalink to comment#

    My god this is cool. Can I have one?!

  35. It’s awesome ….

  36. jon
    Permalink to comment#

    hey, sorry to be a bum but i noticed a number of typos so far in the article…

    Simple a wrap that contains the area
    and hides overflow,

    …That doesn’t belong in the markup because with JavaScript it would be useless.

    maybe it’s just the lack of sleep but they actually confused me :)

    anyways, brilliant work as usual.

  37. Thanks for those catches Jon, I updated them. I need an editor =P

  38. Mariusz Cygan
    Permalink to comment#

    Strange thing happens, when I want to have more than three slides I need to increase the width in #mover. Otherwise, the divs are not placed in one row and the sliding does not work. Could you confirm on that?

  39. Ah yes, good catch Mariusz. I have updated the code yet again to set the #mover width with the JavaScript, so no adjustments are needed there.

  40. jon
    Permalink to comment#

    just me?

    are those arrow-buttons that say “learn more” meant to trigger a slide change? cause they’re not responding to my manic clicking … i hope its not my compu!

    : O

  41. Nick Barnes
    Permalink to comment#

    Thanks so much..this is exactly the thing I’ve been looking for.

  42. Pino Silvestre
    Permalink to comment#


    I saw that when I block javascript, the content of the markup is complete, but I can view only the first item.

    Is it possible to degrade to a normal page without animation when javascripts are no activated?

    Thank you very much, and my compliments for being such a good mentor.

  43. Permalink to comment#

    Looks fine in IE7 now, however, it still seems to display all of the tabs simultaneously in IE6. Unfortunately for me, I’m required to have IE6 compatible designs. I’ll definitely use this on side projects, and I’ll be monitoring this page, hopefully an IE6 fix will surface.

  44. Gotta give this a go at some point!

    Nice work Chris!

  45. Permalink to comment#

    u rock. this is exactly what i was looking for. however, i do have to support IE 6, too. my next step: do a google search for start/stop slider

  46. tzDaFoo
    Permalink to comment#

    I’ll have to second the notion that you are totally mojo madness there!
    This is insanely awesome, flyout, slidin’ in, movin’ on.
    Can you make the it a little more whikkety, whickeddy wicked?

  47. Permalink to comment#

    Really really nice work! Unfortunately is not IE6 (bleach) compliant :(
    @sergi do you found some solution?

  48. Do I put this code in the style or body section. I hope to hear from you soon. I got my layout at

  49. veerendra
    Permalink to comment#

    great tool !
    thank you !

  50. Permalink to comment#

    Amazing, more articles like this :)

  51. Dave Ladner
    Permalink to comment#

    Can this be made vertical? Great work, Chris! I have used your stuff before, and I will likely use this, but it would be terrific if I could use it vertically. Same dimensions, like this one stood up on end…

  52. Dan
    Permalink to comment#

    Really great work! I tried to change the dimensions, a little bit smaller… No problems so far – but at every reload the position of the first slide-image is a little bit to high. Any ideas what’s the matter?

  53. Rik
    Permalink to comment#

    dude, nice work!!

    i normaly dont bother commenting, but i just realy like all your work, so thanks again,,,, bb..


  54. Permalink to comment#


    It is a nice piece of work. thanks a lot. I was trying to incorporate it to a wordpress theme. Everything works fine except for IE-6 ( no surprise there) . On IE -6 the entire panels are displayed flat on the screen. Any fix for this?

  55. Permalink to comment#

    Hi Chris,

    I got it to work on IE-6 making a change in the css. I changed the position of #mover from relative to absolute.

    # mover {
    width: auto;
    position: absolute;

    This is working for me . Is there any other fix for this issue?

  56. kt
    Permalink to comment#

    The download Link is not working. Can you please fix it.

  57. Nick Barnes
    Permalink to comment#

    Jinsona…..Thanks for the IE6 fix. However you had width changed to “auto”. I could not get it to work this way. I left everything the same and only changed position to “absolute” and it works great.

  58. Justin
    Permalink to comment#

    How would you add buttons to select next and previous panels? That way you could scroll through at your own pace.

  59. billy
    Permalink to comment#

    How difficult would this be to get next or previous buttons and small slide previews so that one could go directly to a specific slide.

  60. MTN
    Permalink to comment#

    Is it possible to incorporate this into a drupal site as a block? I would like to use it on a high school online newspaper.

  61. Following Cameron Moll’s example, “Good Designers Copy, Great Designers Steal“, I straight out just copy and pasted this into my project. There are many scripts/tutorials similar to yours, but none as all encompassing and as easily explained as this one.

    Thanks Chris, you saved me a couple hours of work!

  62. Kiet
    Permalink to comment#

    I love this slider, I would like to add one more slide instead of three. How can I do it. Thanks for your helping.

  63. Nick
    Permalink to comment#

    Hi Chris

    Great article!!!!

    Just viewed the demo in IE6 mmm…. still shows all 3 areas horizontally.

    Has a cure for the IE6 curse been found for this great slider?

  64. marco
    Permalink to comment#

    hi guys, great script!

    but what if I want to have the slideshow stopped when the page loads?

    (and activate it by pressing the button “start”)

  65. Permalink to comment#


    I really like it, but I have a question:

    Could this be adjusted so that the sliding div has two arrows on each side, to manually (and not auto) slide it’s contents? Can you please share how?


  66. walther
    Permalink to comment#

    Hey first of all thanx for the awesome tutorial.

    I just have one problem/question.

    Can i use this on a internet website?

    Because it works great on my local dev server haha, but in my live online server nothing happens when the slider action is supposed to.


    • Walther
      Permalink to comment#

      Fixed it, error was on my part hahaha.

      Thanx for the great tutorial!

  67. amit
    Permalink to comment#

    Hi Chris, How i can add start and stop image i am confused…

  68. Brian
    Permalink to comment#


    I love the look of this slider, but my question is, how do you customize it so that it aligns to the left of the page instead of the center? I’ve tried changing a few things in the style.css file but so far haven’t found a way to change the alignment. The closest I got was adding a negative left attrib in the #mover section, (e.g. #mover {left: -180px;}) but that doesn’t really work consistently with different sized browsers.

    Is there something in the JS that is aligning it to center? Any thoughts?

  69. Heather Weinberger

    I need to design a website with a slot machine on the landing page that may just have a default still image where the number would pop up. Then I need that area to act as a start / stop slider every time someone pushes a button, just like a real slot machine. We will have short one line testimonials put up instead of numbers. This coding looks something close to what we need, but any help?

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".