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:
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: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: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 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.
{
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.
{
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: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.
{
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 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: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.
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!
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.
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...
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
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.
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 fromslider.style.height.So the else statement in
SlideUpRunwill look something like this:sliderHeight -= sliderSpeed;
if(sliderHeight < 0)
sliderHeight = 0;
slider.style.height = sliderHeight + 'px';
Even though
slider.style.heighthas 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'.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.
07/12/2007 - 03:54
Is there a way to download a packaged version?
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.
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??
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
innerHTMLwhen the panel is finished sliding. So now that table cell would look something like: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
SlideUpRunandSlideDownRun, add the code to change theinnerHTMLof the table cell at the end of the 'if' statements. So inSlideUpRun, you'll have:{
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 theinnerHTMLto a '-'.You can replace the '+' and '-' with image tags if you want a more graphical look to the sliders. Enjoy.
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.
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!
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?
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.
01/21/2008 - 19:54
I’m impressed. Great tutorial
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/
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
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?
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.
05/23/2008 - 09:58
Here's a new tutorial on how to create sliding panels which start up and slide down.
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.
02/27/2011 - 14:57
In addition to changing both heights to 0, you should also edit the script to look like this:
{
if(sliding)
return;
sliding = true;
if(sliderHeight == 0)
sliderIntervalId = setInterval('SlideDownRun()', 30);
else
sliderIntervalId = setInterval('SlideUpRun()', 30);
And it works like a charm :)
05/19/2008 - 23:43
very simple but excellent sliding tutorial. thanks for providing this type of code.
dev
07/14/2008 - 16:11
Hi,
How to change web page view according to scren resolution.Thanks in Advance.
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
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
07/31/2008 - 03:30
good thanks
09/12/2008 - 11:08
Is there a way to start the window at a closed state, and expand the window on click?
09/12/2008 - 11:50
Yes, check out this tutorial.
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.
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 !
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!
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 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>
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 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';
}
}
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';
}
}
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?
01/21/2010 - 19:40
Superb. Thx a lot!
02/11/2010 - 05:44
What a fantastic and helpful tutorial. Thank you.
10/12/2010 - 19:45
not so good but its better thn previous
01/30/2011 - 07:02
very helpful tutorial Thanks a lot.
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);
}
}
}
}
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?
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.
Add Comment
[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.