Javascript and CSS Tutorial - How to make Sliding Panels
|
Making Sliding Panels with Javascript and CSS This tutorial provides a step-by-step guide to creating sliding panels (like the one on the left) 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. |
<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. |
Posted in CSS, Javascript, All Tutorials by The Reddest |
29 Responses
Tracebacks / Pingbacks
-
Best of April 2007 | Best of the Month
September 24th, 2007 at 1:53 pm -
All in a days work…
October 26th, 2007 at 10:13 am

May 30th, 2007 at 1:25 pm
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!
May 31st, 2007 at 7:53 pm
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.
July 2nd, 2007 at 2:30 pm
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
July 2nd, 2007 at 8:45 pm
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.
July 7th, 2007 at 12:14 pm
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.
July 12th, 2007 at 4:54 am
Is there a way to download a packaged version?
July 16th, 2007 at 6:18 pm
@Rodrigo
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’.
@Premium Mike
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.
August 6th, 2007 at 4:27 pm
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??
August 7th, 2007 at 11:23 am
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.
August 8th, 2007 at 4:02 pm
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.
August 24th, 2007 at 2:46 pm
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!
October 16th, 2007 at 10:39 am
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?
January 9th, 2008 at 7:45 pm
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.
January 21st, 2008 at 8:54 pm
I’m impressed. Great tutorial
January 31st, 2008 at 6:11 am
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/
May 8th, 2008 at 6:02 am
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
May 20th, 2008 at 12:43 am
very simple but excellent sliding tutorial. thanks for providing this type of code.
dev
May 21st, 2008 at 8:27 am
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?
May 21st, 2008 at 8:49 am
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.
May 23rd, 2008 at 10:58 am
Here’s a new tutorial on how to create sliding panels which start up and slide down.
July 14th, 2008 at 5:11 pm
Hi,
How to change web page view according to scren resolution.Thanks in Advance.
July 25th, 2008 at 1:24 pm
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
July 31st, 2008 at 4:30 am
good thanks
September 12th, 2008 at 12:08 pm
Is there a way to start the window at a closed state, and expand the window on click?
September 12th, 2008 at 12:50 pm
Yes, check out this tutorial:
http://blog.paranoidferret.com/index.php/2008/05/23/javascript-sliding-panels-starting-the-panels-up/
September 18th, 2008 at 6:42 am
” 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.
September 19th, 2008 at 5:47 pm
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 !