Javascript and CSS Tutorial - How to make Sliding Panels

Skill

Javascript and CSS Tutorial - How to make Sliding Panels

Posted in:

This tutorial provides a step-by-step guide to creating sliding panels (like the one shown below) using nothing but Javascript and CSS. We used these panels on Gaming Textures so the user could hide parts of the page when they weren't being used.

The first thing we need to do is create all the elements that make up the panel. For this example I went with div elements, because they are really easy to position and resize. There are a total of 4 div elements that make up the entire sliding panel. There are 2 divs in the header, 1 div which slides up and down, and another div which just holds everything. Below is the final result of what we will be building today - have fun clicking on the X in the upper right corner to make it slide up and down.

X
Click the 'X' in the top-right corner to expand and contract this sliding panel.

Ok, let's get starting. We are first going to create the div that will hold everything:

<div style="position:relative;width:250px;height:250px;"></div>

This is the div that is going to hold the other parts of the sliding panel. I made it 250x250, but you can make it any size that fits your needs. I went with position:relative; so the panel flows with the rest of the page contents.

As you're probably already aware, this code produces a large invisible square. Let's put on the header so it looks more like a typical window. The header consists of an 18 pixel tall div across the top and another square div which will hold the 'X' button.

<div style="position:relative;width:250px;height:250px;">
  <div style="position:absolute;left:0px;top:0px;width:250px;height:18px;
     background-color:#3B587A;">

    <div style="position:absolute;top:0px;right:0px;width:18px;height:18px;
       background-color:#85A1C2;">

    </div>
  </div>
</div>

At this point, you should see something along these lines:

Now let's add the div that will actually be doing the expanding and contracting.

<div style="position:relative;width:250px;height:250px;">
  <div style="position:absolute;left:0px;top:0px;width:250px;height:18px;
     background-color:#3B587A;">

    <div style="position:absolute;top:0px;right:0px;width:18px;height:18px;
       background-color:#85A1C2;">

    </div>
  </div>
  <div id="sliderElementId" style="position:absolute;top:18px;left:0px;
     width:250px;height:232px;background-color:#A6BBCD;">

  </div>
</div>

The above code will produce something that looks very similar to the finished product. Placing the 'X' in the top-right corner is trivial, so I'll save it for the finished code at the end of this post. Since Javascript will be modifying this element, we need to assign it an ID. I chose "sliderElementId", but you can choose whatever you want.

Now that the panel is basically complete, let's start adding some Javascript code to handle the sliding. Let's begin by declaring some global variables:

var sliderIntervalId = 0;
var sliderHeight = 232;
var sliding = false;
var slideSpeed = 10;

sliderIntervalId holds the id of the interval that will be animating the slider. I'll explain what that means in more detail later. Since the slider starts expanded, I set sliderHeight equal to 232 - the height of "sliderElementId". sliding is a boolean which keeps track of whether or not the panel is currently sliding. This keeps it from trying to slide again if the user clicks the 'X' while it is already sliding. slideSpeed controls how fast the panel will contract and expand.

Let's now create the function that will be called when the 'X' is clicked.

function Slide()
{
   if(sliding)
      return;
   sliding = true;
   if(sliderHeight == 232)
      sliderIntervalId = setInterval('SlideUpRun()', 30);
   else
      sliderIntervalId = setInterval('SlideDownRun()', 30);
}

The first thing I do is check whether or not the panel is currently sliding. If it is, I simply return out of the function without doing anything. If it makes it past that check, we are going to slide the panel either up or down so I set the sliding variable to true. After that I need to determine whether to slide the panel up or slide it down. I do this by simply checking the value of sliderHeight. If sliderHeight is 232, it's expanded, so I need to contract it. Otherwise, I need to expand it.

I used Javascript's setInterval function to control the animating of the panel. setInterval takes a function to call and the time interval to call it at. I set it to 30, which means the function will be called every 30 milliseconds. I set sliderIntervalId equal to the return value, so I can cancel the interval later when the panel is finished sliding.

I created two functions that setInterval will call: SlideUpRun() and SlideDownRun(). Let's look at SlideUpRun() first.

function SlideUpRun()
{
   slider = document.getElementById('sliderElementId');
   if(sliderHeight <= 0)
   {
      sliding = false;
      sliderHeight = 0;
      slider.style.height = '0px';
      clearInterval(sliderIntervalId);
   }
   else
   {
      sliderHeight -= slideSpeed;
      if(sliderHeight < 0)
         sliderHeight = 0;
      slider.style.height = sliderHeight + 'px';
   }
}

The first thing this function does is get the element from the id that was assigned earlier to the sliding panel. The next thing I do is check to see whether or not the panel is finished sliding. I do this by checking the value of sliderHeight. If the value is less than or equal to 0, the panel is fully retracted. If it's finished sliding, I set the value of sliderHeight to 0, I set the height style of the sliding panel to 0 pixels and call clearInterval to stop the animation.

If the panel is not finished sliding, I need to decrease the height by the amount defined in slideSpeed. I then check to make sure the value is not less than zero. Negative values can throw Javascript errors. I then set the height style of the sliding panel to the new sliderHeight.

Let's hook in what we have so far and see what happens. We'll need to add an onclick event handler to the div which will hold the 'X' button. This code will launch Slide(); whenever the div is clicked.

<div style="position:relative;width:250px;height:250px;">
  <div style="position:absolute;left:0px;top:0px;width:250px;height:18px;
     background-color:#3B587A;">

    <div onclick="Slide();" style="position:absolute;top:0px;right:0px;
       width:18px;height:18px;background-color:#85A1C2;">

    </div>
  </div>
  <div id="sliderElementId" style="position:absolute;top:18px;left:0px;
     width:250px;height:232px;background-color:#A6BBCD;">

  </div>
</div>

You should now see the above sliding panel. When the square on the right of the header is clicked, the panel should retract like the above example. If you click the square again, a Javascript error will be thrown because we have not yet defined the function to control expanding the sliding panel. Let's do that now.

function SlideDownRun()
{
   slider = document.getElementById('exampleSlider');
   if(sliderHeight >= 232)
   {
      sliding = false;
      sliderHeight = 232;
      slider.style.height = '232px';
      clearInterval(sliderIntervalId);
   }
   else
   {
      sliderHeight += slideSpeed;
      if(sliderHeight > 232)
         sliderHeight = 232;
      slider.style.height = sliderHeight + 'px';
   }
}

This function is very similar to SlideUpRun(). The only major difference is now I'm checking to see if the panel is greater than or equal to 232 to see whether or not the panel is finished sliding. I also increment sliderHeight instead of decrementing it.

That's all the code required for a basic sliding panel. I'll finish up the tutorial by posting all the code required to duplicate the sliding panel that is at the top of this post.

var sliderIntervalId = 0;
var sliderHeight = 232;
var sliding = false;
var slideSpeed = 10;

function Slide()
{
   if(sliding)
      return;
   sliding = true;
   if(sliderHeight == 232)
      sliderIntervalId = setInterval('SlideUpRun()', 30);
   else
      sliderIntervalId = setInterval('SlideDownRun()', 30);
}

function SlideUpRun()
{
   slider = document.getElementById('exampleSlider');
   if(sliderHeight <= 0)
   {
      sliding = false;
      sliderHeight = 0;
      slider.style.height = '0px';
      clearInterval(sliderIntervalId);
   }
   else
   {
      sliderHeight -= slideSpeed;
      if(sliderHeight < 0)
         sliderHeight = 0;
      slider.style.height = sliderHeight + 'px';
   }
}

function SlideDownRun()
{
   slider = document.getElementById('exampleSlider');
   if(sliderHeight >= 232)
   {
      sliding = false;
      sliderHeight = 232;
      slider.style.height = '232px';
      clearInterval(sliderIntervalId);
   }
   else
   {
      sliderHeight += slideSpeed;
      if(sliderHeight > 232)
         sliderHeight = 232;
      slider.style.height = sliderHeight + 'px';
   }
}

<div style="position:relative;width:250px;height:250px;margin-bottom:5px;">
  <div style="position:absolute;width:250px;height:18px;left:0px;
       top:0px;background-color:#3B587A;border:1px solid #FFFFFF;">

    <div style="position:absolute;width:18px;height:18px;right:0px;
          top:0px;background-color:#85A1C2;text-align:center;
          border-left:1px solid #FFFFFF;color:#000000;
          cursor:pointer;padding:0px;" onclick="Slide();">

      <table width="100%" height="15px" cellspacing="0" cellpadding="0">
        <tr>
          <td align="center" valign="middle" style="text-size:9pt;">
            X
          </td>
        </tr>
      </table>
    </div>
  </div>
  <div id="exampleSlider" style="position:absolute;top:18px;left:0px;
       width:250px;height:232px;background-color:#A6BBCD;
       border:1px solid #FFFFFF;color:#000000;overflow:hidden;">

    <table width="100%" height="100%">
      <tr>
        <td valign="top" style="padding:3px;">
          Click the 'X' in the top-right corner
          to expand and contract this sliding panel.
        </td>
      </tr>
    </table>  
  </div>
</div>

If you'd like to see sliding panels in action, check out Gaming Textures for some good examples.

Kate
05/30/2007 - 12:25

i love this script and it’s exactly the kind of thing i’ve been looking for to redo my portfolio. one question.. if i wanted to have multiple sliding panels (with each one showing a different piece of artwork) is there a way to code that using the script just once, rather than for each time you use it? ie.. a way for it to call upon different element ids? thanks!

reply

The Reddest
05/31/2007 - 18:53

Absolutely there is. For an example, let's say you wanted two of these.

The first thing you'd have to do is put all the html code in the two places you wanted the panels. Then, you'd need to give the sliding panels different id's. In the above example, the id is "exampleSlider". Let's call the new ones "exampleSlider1" and "exampleSlider2".

The next thing we'd do is modify the Slide() method to take the element you want to slide. Just change the method signature to function Slide(element).

Now, to get the element into the Slide method, we need to modify what the onclick is doing in the top right corner. For the first sliding panel, change the onclick to "Slide(document.getElementById('exampleSlider1'));". For the second one, do the same thing but pass 'exampleSlider2' into document.getElementById.

Now that the element is inside the Slide function, we need a way to get it inside the two run methods. Make a new global variable to hold the element - "var slideElement". In the Slide method, set the variable to the element passed in after the if(sliding) check.

All that's left to do now is use the global slideElement in the two run methods instead of calling 'getElementById'.

This is the quickest way I can think of to get multiple sliding panels. Let us know when you get your portfolio finished, we'd love to see how you implemented these.

reply

frankie
11/15/2010 - 02:23

how should i modify if i want the sliding panel default is in contract not expand but ready to be expand whenever click...

reply

Rodrigo
07/02/2008 - 13:30

Hi,
Loved your code. I'm learning css for a short time and this is a good step forward to mix it with javascript (first timer!!!). Flexible and easy to use and style! However, I didn't manage to have the same behavior in firefox. IE works fine, but there is no behavior in Firefox. Do you know if there any way to make it work in FireFox? Thanks

reply

The Reddest
07/02/2007 - 19:45

I actually developed the code using Firefox, so it works just fine for me. One thing to look at would be Firefox's Error Console: Tools->Error Console. Clear the console, then load your page again and see if there are any errors. Sometime IE is more forgiving than Firefox when it comes to errors.

reply

The Reddest
07/16/2007 - 17:18

You're absolutely right about that being a problem. Here is a solution: instead of using the variable sliderHeight - just parse the height of the panel from slider.style.height.

So the else statement in SlideUpRun will look something like this:

sliderHeight = parseInt(slider.style.height);
sliderHeight -= sliderSpeed;
if(sliderHeight < 0)
   sliderHeight = 0;
   
slider.style.height = sliderHeight + 'px';

Even though slider.style.height has a 'px' in the string, parseInt still works because it parses until it reaches a non-numerical value. So it will just ignore the 'px'.

reply

Ahmed
07/07/2007 - 11:14

This a good script with a very good description .
About the code modification for sliding more than one panel there will be a problem that all the sliding panels will have one "sliderHeight" variable so if a panel slided up all the other panels have to slide down.
I will try to figure out a solution for it.

reply

Premium Mike
07/12/2007 - 03:54

Is there a way to download a packaged version?

reply

The Reddest
07/16/2007 - 17:18

I hadn't designed the code to be packaged - it was more of a way to give coders a technique on which to build their own packages. If I receive more requests for a packaged version, I'll put one together. For now, however, there isn't one available.

reply

Tim
08/06/2007 - 15:27

Great script!! Is there a way we can change the plus sign to minus when the div expands? and make it plus sign when it collapses??

reply

The Reddest
08/07/2007 - 10:23

There sure is! Right now there is a table cell that holds the 'X' in the top-right corner. What you need to do is give that cell an id and set its innerHTML when the panel is finished sliding. So now that table cell would look something like:

<td align="center" valign="middle" id="exampleSlider1X"
   style="text-size:9pt;">
  -
</td>

I set the id to the id of the slider plus an 'X'. This way you can easily do the multiple sliders as mentioned in one of my previous comments. I also replaced the 'X' with a '-' since the panel is expanded by default.

In SlideUpRun and SlideDownRun, add the code to change the innerHTML of the table cell at the end of the 'if' statements. So in SlideUpRun, you'll have:

if(sliderHeight <= 0)
{
   sliding = false;
   sliderHeight = 0;
   slider.style.height = '0px';
   clearInterval(sliderIntervalId);

   //set the cell's innerHTML to '+'
   document.getElementById(slider.id + 'X').innerHTML = '+';
}

Now just do the same thing in SlideDownRun, but set the innerHTML to a '-'.

You can replace the '+' and '-' with image tags if you want a more graphical look to the sliders. Enjoy.

reply

The Reddest
08/08/2007 - 15:02

Hey guys. We just posted a new sliding panel tutorial that uses our new generic animation code. I would highly recommend using that tutorial for sliding panels because it makes the process much easier and much more extensible. Cheers.

reply

Corey Klemow
08/24/2007 - 13:46

Lovely!

Is there any way to make it so the "invisible" part of the box is not taking up space when the box is closed? (i.e. any text below it would be *directly* below it, and be pushed further down when the box opens).

The kicker is that I'm looking for a way to do this without using anything that needs to go into the Head of the page, as I'm looking to add it to a php-based product page in a new shopping cart system I'm about to switch over to. It needs to be something that will work solely in the Body. Any pointers?

I have other options, like simply making the info pop up in a separate window instead of using the slidebox, but your dropdown box is so pretty and so very nearly *almost* what I need that I'd like to see if I can make it work!

Thanks!

reply

Lilly
10/16/2007 - 09:39

Really very nice..
Thanks a lot but I have a simple question. In the examples you gave, I need to know the width of the div, what if I want to set the width of the div to 100% to to width in pixels?? How can I slide the window when I don't know the width and so don't know the new left?

reply

Todd Thelin
01/09/2008 - 18:45

I wanted to let you know that there is an error in your code if the person is following along. In SlideUpRun you call the element sliderElement but in SlideDownRun you call exampleSlider which is not what the div is called. In your full code it is correct. This is a fantastic example. Thank you for sharing with everyone.

reply

David
01/21/2008 - 19:54

I’m impressed. Great tutorial

reply

Bryan
01/31/2008 - 05:11

Hey great tutorial! I am new at this and was wondering if someone could post the code for the completed js and html for multiple sliding panels because some how I got lost and now it's just a mess!! This pretty much sums up what I was going for http://www.gigxl.com/

reply

Chris
05/08/2008 - 05:02

Does anyone know how i can change the code so that when the webpage is opened for the first time the sliding panel is now contracted and requires clicking on the cross to open it?

Thanks

reply

Luc
05/21/2008 - 07:27

I have the same question that Chris.
Does anyone know how i can change the code so that when the webpage is opened for the first time the sliding panel is now contracted and requires clicking on the cross to open it?

reply

The Reddest
05/21/2008 - 07:49

I'll whip up a new tutorial to cover starting the panel contracted. Until then, I would recommend the newer sliding panels tutorial here. It uses our generic animation code, which is a little easier to understand.

reply

The Reddest
05/23/2008 - 09:58

Here's a new tutorial on how to create sliding panels which start up and slide down.

reply

LD
02/17/2011 - 12:52

I found a very easy way to do this.

In the beginning of the script, set your var slideHeight=0

Then set the height of the sliderElement div to 0.

If you leave everything else the same, this should start the slider closed and open it on click. At least it works for me.

reply

bloodyfaster
02/27/2011 - 14:57

In addition to changing both heights to 0, you should also edit the script to look like this:

function Slide()
{
   if(sliding)
      return;
   sliding = true;
   if(sliderHeight == 0)
          sliderIntervalId = setInterval('SlideDownRun()', 30);
   else
      sliderIntervalId = setInterval('SlideUpRun()', 30);

And it works like a charm :)

reply

Devraj
05/19/2008 - 23:43

very simple but excellent sliding tutorial. thanks for providing this type of code.
dev

reply

Shino J K
07/14/2008 - 16:11

Hi,

How to change web page view according to scren resolution.Thanks in Advance.

reply

Nathan Scheffey
07/25/2008 - 12:24

Hi-
Great code first of all, very useful.
I was wondering what it would take to have other elements on the page move around as the panel expands and contracts, rather than having the panel expand over other elements. Would this be a relatively easy CSS change, or is it not possible?
Thanks in advance for any help,
Nate

reply

Andrew Cox
04/01/2009 - 08:31

Hi Nate, did you get an answer to this? I'm trying to do the same. andrew@reactivegraphics.co.uk

reply

Good
07/31/2008 - 03:30

good thanks

reply

Shorewire
09/12/2008 - 11:08

Is there a way to start the window at a closed state, and expand the window on click?

reply

The Reddest
09/12/2008 - 11:50

Yes, check out this tutorial.

reply

Majid
09/18/2008 - 05:42

" u need to include in ||||||||->style="position:absolut;" then only it works as per ur demo "

Click the 'X' in the top-right corner to expand and contract this sliding panel.

reply

Jota
09/19/2008 - 16:47

The code does'nt work for me on IE

Please check this out:

http://www.moosic.xf-s.com/slide.php

I hope you can help me to solve it.

Thanks !

reply

rw1
01/29/2009 - 00:17

hello,

would anybody be able to tell me how to get this 'docked' on the left side of the screen in a fixed position? (ie so it stayed in the same place when scrolling). thank you very much!

reply

manray
04/28/2009 - 20:22

Hi! Great Script! But I am having some difficulty, with the html. Here is the code.The slider is working, but it is not 'hiding' the meat of the div. How can I fix this?

<div id="editdocs" style="display:none;" class="draggable">
<div style="position:absolute;left:0px;top:0px;width:700px;height:18px;background-color:#3B587A;"></div>
<div onclick="Slide(document.getElementById('editdocs'));" style="position:absolute;top:0px;right:0px;width:18px;height:18px;background-color:#85A1C2;"></div>
<br />
<p align="center"><textarea name="docs" rows="20" cols="80">
</textarea></p>
<p align="center"><input type="button" onclick="popup('editdocs');" value="Close" class="btn"/></p>
</div>

reply

manray
04/29/2009 - 07:26

okay I got multiple sliders to work, but one small inconvenience. If I have two sliders open, and close one, than try to close the second, the second one opens instead. Here is the code.

var sliderIntervalId = 0;
var sliderHeight = 482;
var sliding = false;
var slideSpeed = 10;
var slideElement;

function Slide(element)
{
   if(sliding)
      return;
   sliding = true;
   slideElement = element;
   if(sliderHeight == 482)
      sliderIntervalId = setInterval('SlideUpRun()', 5);
   else
      sliderIntervalId = setInterval('SlideDownRun()', 5);
}

function SlideUpRun()
{
   slider = slideElement;
   if(sliderHeight <= 0)
   {
      sliding = false;
      sliderHeight = 0;
      slider.style.height = '0px';
      clearInterval(sliderIntervalId);
   }
   else
   {
      sliderHeight -= slideSpeed;
      if(sliderHeight < 0)
         sliderHeight = 0;
      slider.style.height = sliderHeight + 'px';
   }
}

function SlideDownRun()
{
   slider = slideElement;
   if(sliderHeight >= 482)
   {
      sliding = false;
      sliderHeight = 482;
      slider.style.height = '482px';
      clearInterval(sliderIntervalId);
   }
   else
   {
      sliderHeight += slideSpeed;
      if(sliderHeight > 482)
         sliderHeight = 482;
      slider.style.height = sliderHeight + 'px';
   }
}

reply

Shriram
10/07/2009 - 18:14

Better way to do this is

var sliderIntervalId = 0;
var sliderHeight ;
var sliding = false;
var slideSpeed = 10;
var slideElement;
var initialHeight;
function Slide(element)
{
if(sliding)
return;
sliding = true;
slideElement = document.getElementById(element);
initialHeight=parseInt(slideElement.style.height);
sliderHeight=initialHeight
if(sliderHeight == initialHeight)
sliderIntervalId = setInterval('SlideUpRun()', 5);
else
sliderIntervalId = setInterval('SlideDownRun()', 5);
}

function SlideUpRun()
{
slider = slideElement;
if(sliderHeight <= 0)
{
sliding = false;
sliderHeight = 0;
slider.style.height = '0px';
clearInterval(sliderIntervalId);
}
else
{
sliderHeight -= slideSpeed;
if(sliderHeight < 0)
sliderHeight = 0;
slider.style.height = sliderHeight + 'px';
}
}

function SlideDownRun()
{
slider = slideElement;
if(sliderHeight >= initialHeight)
{
sliding = false;
sliderHeight = initialHeight;
slider.style.height = 'initialHeightpx';
clearInterval(sliderIntervalId);
}
else
{
sliderHeight += slideSpeed;
if(sliderHeight > initialHeight)
sliderHeight = initialHeight;
slider.style.height = sliderHeight + 'px';
}
}

reply

lpngo
06/03/2009 - 21:20

Hi, this looks fantastic. I wanted to know if elements in the div tags can be table rows and cells?

reply

Boll
01/21/2010 - 19:40

Superb. Thx a lot!

reply

Anonymous
02/11/2010 - 05:44

What a fantastic and helpful tutorial. Thank you.

reply

ali
10/12/2010 - 19:45

not so good but its better thn previous

reply

vivekaTheGreat
01/30/2011 - 07:02

very helpful tutorial Thanks a lot.

reply

mikbak
02/17/2011 - 08:57

I've added a simple extra that closes all open sliders when one is opened.

Got the original code from 'http://www.harrymaugans.com/2007/03/24/one-click-toggle-for-sliding-animated-div/'

put this at the end of the function SlideDown()..

 
function closeopened(objID) {
        var elems = document.getElementsByTagName("*");
        for (var i=0; i<elems.length; i++) {
        if (elems[i].id.indexOf('myDiv_') == 0) {
        if (elems[i].id.indexOf('myDiv_'+objID) != 0){
                slideUp(elems[i].id);
                                }
                        }
                }
}

reply

LD
02/17/2011 - 13:58

I can't get this to work. Can you give a bit more info on what you change those variables to that might help a beginner like me?

reply

onetouchdesign
12/22/2011 - 19:49

Is there a way to make it expand up and mover the top block up with it, anchoring it to the bottom? I figured out how to move it up but it covers the trigger to move it back down.

reply

Add Comment

Put code snippets inside language tags:
[language] [/language]

Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]

See here for supported languages.

Javascript must be enabled to submit anonymous comments - or you can login.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.