In this tutorial, we're going to combine the original tutorial on Sliding Panels with our new tutorial on Generic Animation. Using our generic animation code, making sliding panels becomes much easier. You can download the Javascript code for generic animation here.
For this tutorial, I'm going to show how to make a few different types of sliding panels. Hopefully you'll have a good understanding of how to use the generic animation code to make all sorts of interesting and unique sliding panels by the end of this post.
Let's start with a standard vertical slider. In this example, when you click the header, the panel will contract and expand exactly like it does in our first sliding panel tutorial.
Here's the HTML code required to make the above example.
<div style="position:relative;
width:150px;
height:170px;
top:0px;
left:0px;">
<div id="exampleHeader1"
style="position:absolute;
width:150px;
height:20px;
top:0px;
left:0px;
background:#3b587a;
text-align:center;
color:#FFFFFF;"
onclick="slideExample1('examplePanel1', this);">
^^^
</div>
<div id="examplePanel1"
style="position:absolute;
width:150px;
height:130px;
top:20px;
left:0px;
background:#a6bbcd;
overflow:hidden;">
Content
</div>
</div>
There's nothing too special about this code. There's one div which just holds the header and the sliding panel. The next div, with the id "exampleHeader1", is the one that is going to be listening for the onclick event. I put the text '\^\^\^' inside this div so the user has a visual indication of the state of the sliding panel. The div with the id of "examplePanel1" is the div that we will actually be animating. Now let's look at the Javascript code to make this panel slide.
function slideExample1(elementId, headerElement)
{
var element = document.getElementById(elementId);
if(element.up == null || element.down)
{
animate(elementId, 0, 20, 150, 0, 250, null);
element.up = true;
element.down = false;
headerElement.innerHTML = 'vvv';
}
else
{
animate(elementId, 0, 20, 150, 130, 250, null);
element.down = true;
element.up = false;
headerElement.innerHTML = '^^^';
}
}
As you can see, the Javascript code required to make a sliding panel has
been reduced significantly from our original tutorial. This is the
function that is called when the slider's header is clicked. The first
thing I do is get the sliding panel div element by calling
getElementById. I then check to see which direction I need to slide
the panel. I'm storing the state of the panel directly in the panel's
div element. If I haven't slid the panel yet (element.up == null), or
element.down is true, I need to slide the panel up. Otherwise, I need to
slide the panel down. Thanks to the animate function provided by the
generic animation code, sliding the panel only takes one line of code.
The animate function takes the id of the element, the new left position,
the new top position, the new width, the new height, the animation
length (in milliseconds), and a callback function. So, to slide the
panel up, I want to set the new position to 0, 20 and the new size to 0,
250. I want the animation to take 250 milliseconds and I don't want any
function called when the animation is finished - so I set it to null.
Next I set the state of the panel by setting element.up to true and
element.down to false. Lastly I change the text in the header to
'vvv'.
To slide the panel back up, the animate function is called again with
the panel's original position and size. Next, element.down is set to
true and element.up is set to false and the header's text is changed
to '\^\^\^'.
Now let's look at a slider that's very similar to the vertical one but slightly more interesting. This sliding panel will slide horizontally from left to right when the header is clicked.
Here's the HTML code:
<div style="position:relative;
width:150px;
height:170px;
top:0px;
left:0px;">
<div id="exampleHeader2"
style="position:absolute;
width:20px;
height:150px;
top:0px;
left:0px;
background:#3b587a;
text-align:center;
color:#FFFFFF;"
onclick="slideExample2('examplePanel2', this);">
<<br /><<br /><
</div>
<div id="examplePanel2"
style="position:absolute;
width:130px;
height:150px;
top:0px;
left:20px;
background:#a6bbcd;
overflow:hidden;">
Content
</div>
</div>
The HTML code is nearly identical to the vertical slider code except for changing the orientation of the header and panel. I also changed the text in the header to a series of \<'s. Let's see the Javascript code:
function slideExample2(elementId, headerElement)
{
var element = document.getElementById(elementId);
if(element.up == null || element.down)
{
animate(elementId, 20, 0, 0, 150, 250, null);
element.up = true;
element.down = false;
headerElement.innerHTML = '><br />><br />>';
}
else
{
animate(elementId, 20, 0, 130, 150, 250, null);
element.down = true;
element.up = false;
headerElement.innerHTML = '<<br /><<br /><';
}
}
This code is exactly the same as before except for the parameters passed into the animate function and the text in the header div. Instead of sliding the panel up and down we're sliding the panel left and right. So to slide the panel left we need to keep the position of the panel the same at 20,0 and resize it to 0x150. The animation will still take 250 milliseconds with a callback of null. To slide the panel right, just reset the size of the div to its original value - 130x150.
Now that we have the basic sliding panels out of the way, let's look at some more interesting ones. This panel will slide diagonally into the top-left square.
<div style="position:relative;
width:150px;
height:170px;
top:0px;
left:0px;">
<div id="exampleHeader3"
style="z-index:1;
position:absolute;
width:20px;
height:20px;
top:0px;
left:0px;
background:#3b587a;
text-align:center;
color:#FFFFFF;"
onclick="slideExample3('examplePanel3', this);">
-
</div>
<div id="examplePanel3"
style="position:absolute;
width:150px;
height:150px;
top:0px;
left:0px;
background:#a6bbcd;
overflow:hidden;">
<br /><br />Content
</div>
</div>
Again, the HTML code is very similar to the previous example. Since the square sits on top of the sliding panel, I needed to set its z-index to 1 so it was not hidden behind the panel. I set the text in the square to '-', which is switched to '+' when the panel is slid in.
function slideExample3(elementId, headerElement)
{
var element = document.getElementById(elementId);
if(element.up == null || element.down)
{
animate(elementId, 0, 0, 20, 20, 250, null);
element.up = true;
element.down = false;
headerElement.innerHTML = '+';
}
else
{
animate(elementId, 0, 0, 150, 150, 250, null);
element.down = true;
element.up = false;
headerElement.innerHTML = '-';
}
}
This time we want the size of the panel to be 20x20 when it's slid in, which is the size of the top-left square. When the panel slides back out, the size is returned to its original 250x250. The text in the square is alternated between '+' and '-' depending on the state of the panel. Other than that, the code hasn't changed from the previous two examples.
The generic animation function has the flexibility to create some complex animations. Let's create a sliding panel that uses multiple motions to complete a slide. When the square is clicked, the panel will first slide left and then slide up.
<div style="position:relative;
width:150px;
height:170px;
top:0px;
left:0px;">
<div id="exampleHeader4"
style="z-index:1;
position:absolute;
width:20px;
height:20px;
top:0px;
left:0px;
background:#3b587a;
text-align:center;
color:#FFFFFF;"
onclick="slideExample4('examplePanel4', this);">
-
</div>
<div id="examplePanel4"
style="position:absolute;
width:150px;
height:150px;
top:0px;
left:0px;
background:#a6bbcd;
overflow:hidden;">
<br /><br />Content
</div>
</div>
This code is exactly the same as the diagonally sliding panel, so let's dive right into the Javascript.
var slideElement = null;
function slideExample4(elementId, headerElement)
{
slideElement = document.getElementById(elementId);
if(slideElement.up == null || slideElement.down)
{
slideUpStep1();
slideElement.up = true;
slideElement.down = false;
headerElement.innerHTML = '+';
}
else
{
slideDownStep1();
slideElement.down = true;
slideElement.up = false;
headerElement.innerHTML = '-';
}
}
function slideUpStep1()
{
animate(slideElement.id, 0, 0, 20, 150, 250, slideUpStep2);
}
function slideUpStep2()
{
animate(slideElement.id, 0, 0, 20, 20, 250, null);
}
function slideDownStep1()
{
animate(slideElement.id, 0, 0, 20, 150, 250, slideDownStep2);
}
function slideDownStep2()
{
animate(slideElement.id, 0, 0, 150, 150, 250, null);
}
The first thing you might notice is the global variable slideElement.
We need a variable to store what div is currently sliding because the
callback to the animate function can't except parameters. The function
slideExample4 is the same as the previous example except that I've
moved the call to animate into slideUpStep1. When slideUpStep1 is
called, the panel is first slid left and slideUpStep2 is passed into
animate as the callback. That means as soon as the the panel is done
sliding left, slideUpStep2 will be called to slide it up. To slide the
panel back out, the process is simply reversed using slideDownStep1
and slideDownStep2.
That's it for creating sliding panels with our generic animation function. As you can see, using generic animation makes the process of creating sliding panels very simple and the sky's the limit as to how creative you want the slide process to be.
Source Files:
hey! i have read the previous and new tutorial. in the new tutorial i was hoping you will show how to expand the div if the number of textlines in the div are unknown. for example if the text with unknown length is from a webserver.
Nice one :-)
Is it possible to alter the code so the div is hidden when the page is loaded?
i tried adding onload="slideExample1('examplePanel1', 'exampleHeader1');" to the body element, but it doesnt seem to do the trick.
tia,
If I understand you correctly, and you want the panel to start contracted, then it is definitely possible.
Here's the changes to make the first example start contracted: 1. Change the height style to 0px instead of 130px.
?2. Change the header text from "\^\^\^" to "vvv".
?3. In the JS function, slideExample1, change the if statement to if(element.up == false){...}.
That should be it. Now the panel will start contracted and expand down when it's clicked for the first time.
I am wondering in somebody make it so there are more than one panels under the first one and when you expand one - other collapsed?
Great code you got here. One question lingers though, how do I "Put it all together"? I see the HTML code, then the JS code, but I really don't know how to put them together. When JS is involved, I'm always stumped.
Thanks.
Just for you Yata, we've written another tutorial that explains how to put the HTML and Javascript together.
Thank you. That completely solved the problem. I'll be sure to look around at the other tutorials now that I know how to use them.
Thanks again!
I am interested in example 2. Is these a way to make it slide from right to left?
Great code!
I have a problem though... I tried to alter your code to make the panel start contracted. I works in Firefox, but for some reason in IE7 the panel doesn't start contracted. Any idea on how to solve this?
It seems that IE7 has an overflow issue that I'm running into where it won't set the height to anything less than the minimum height at which all the content can be shown. If I pre-set the height to 1 (slider.style.height = 1;) (not zero! I don't know why!?) it works for me.
Also, for some IE7 animations to work it seems that I need to set the top and left element settings in the javascript, otherwise it won't work. I have no idea why this is or what I'm messing up to cause this? Oh well, pre-setting isn't a big deal - just weird.
First off, great scripts scripts, just what I was looking for, so thank you. Also to covenant design, its not your fault or bad coding, IE is just dumb and doesn't know what left is. Also,I have been trying to get the diagonal slider to work but i keep coming up empty. Is that the complete code or should I be looking at other code to combine it with and if so, what?
Also, I am trying to combine the diagonal slider with the side slider into one button, this will probably get alot easier once i get the diagonal code to work anyways but im wondering if anyone could help me do this. Im trying to make a page that is just a simple page with the slide bar on the side. Once the slide bar is clicked, I want the slider to move out and the diagonal slider to cover the other half of the page, any suggestions on how i should do this would be most appretiated. thx u!
Hello, I came across this tutorial when searching for sliding panels. I am using the slideExample2 code. I am trying to figure out how to stop the panel from displaying when the page is loaded.
I tried using the method in comment 4 but I still can not get the panel to start contracted.
Any ideas?
Any help would be appreciated!
Thanks
dips
I partially fixed the "startup not contracted" problem. Here is my solution,...
?1) First I simplified the slideExample1() function by breaking it out into 2 other functions. 2) That means I took each part of the "if" statement and made new functions out of them. 3) In the end I get 3 functions like so,.. function slideExample1(elementId, headerElement) { ... } function slideUp(element, elementId, headerElement, title) { .... } function slideDown(element, elementId, headerElement, title) { ... } 4) So the "if" statement is simply calling the slideUp() and slideDown() functions. 5) Then I added an "onload" callback for my html body tag 6) That means I changed the tag of my html to look like this,... 7) And I added a new function "pageload" to the html. Something like this,... function pageload() { var element = document.getElementById("slideExample2"); var header = document.getElementById("examplePanel2"); slideUp(element, "slideExample2", header, "\^\^\^"); } 8) Concluding explanation: All I have done is tell my html page to call the pageLoad() function when it is loaded by the browser. The pageload() function simply calls the slideUp() function to "close" the panel. So that just means that when my page is first opened, the panel will show. But it immediately gets closed. It happens so fast that I couldn't tell that the panel wasn't contracted at the beginning.
This isn't a perfect solution. I would have preffered not to do this "sleight-of-hand" solution. But I'm not an javascript guru and this is the best I could come up with. It satisfy my needs but may not completely satisfy yours. you'll need to tinker around with this already excellent javascript code.
I hope this helps some people pengster
Here's a new tutorial on how to create sliding panels which start up and slide down.
Lets say I have a existing css sheet, can you show me an example of the first tutorial how the html would look and css additions to current css sheet?
Also can you include in the html an example to call to the javascript if place as a file on server?
I know I'm asking alot but also in this version I like to see when onclick the \^\^\^ is pushed down like a tab sorta. So in reverse the \^\^\^ would be the bottom when you click to close.
Thanks
Still Learning
Hello, I want first to say that your code is great and does just what I've been looking for. I only need a single little twist on it - imagine the boundaries of the sliding panel "pushing away" neighboring content as the panel expands. Not only that, but the neighboring content would "move in" to fill the space left after the sliding panel is collapsed. Would much appreciate your help and input on that, thanks for your time.
hey great work, kuddos, i am trynig some thing same in my application. But my requirement is initially it should not be visible, and when i press button it sholud slide and sholud go back. Also the it should slide from bottom to top and back from top to bottom. thanks in advance...
Good one
how can I make a series of slidding panels fade rather than slide
We don't have an example showing exactly that, but we do have a tutorial showing how to do fading in Javascript. You shouldn't have too much trouble combining the two into what you're looking for.
i'm really stuck on trying to make example 2 have the header on the right side of the div and the panel expand to the left and contract back to the right.
I figured it out, I modified this script nicely to slide out hidden panels from right to left. Check it out:
http://eferrer.info
currently broken for firefox 2.x and safari though.
is this script compatible with firefox 2.x and safari?
The scripts were developed under Firefox 2 so I can definitely say they work there. Typically all Javascript that we post is tested under every major browser (IE, Opera, FF, and Safari). However, this one being almost a year old, I can't remember if it was or not.
I checked out your site and it's a great use of sliding panels. It's a little buggy in FF3 when one of the panels contains Flash, but Flash has always been a hassle when you're trying to hide it behind html elements.
Yeah cool site. I think that if you remove the flash video from the panel before sliding it and add it after sliding it, it would probably work alright.
Thanks Eddie, great slide. If you don't mind can you please elaborate a little on what have you changed to slide from right, have you made changes to "animation.js" or ...
Thanks. -DV
Well the flash isnt the issue because some of the panels don't have flash and they still do not work for firefox 2 or safari. I have no clue what that issue is.
It's working fine for firefox 3, there is a slight flicker with the flash elements. On IE it works pretty perfect.
I still cant get this script to work under firefox 2 or safari, i'm calling it like this:
i've taken out the header element. you can see it live on my site, but its kind of messy code, i've been testing it on my system on a simplified code, but nothing. any hints?
whoops code error on previous comment.
im calling it like (in brackets of course)
i figures it out, the expanding div, in this page "examplePanel" has to be below "exampleHeader".
if not then it wont work in firefox 2 or safari
Very nice article about animation and sliding. Can someone suggest what I can do to slide Horizontal from "Right" to "Left". Thanks any response would be appreciated.
-DV
to make it slide from right to left, you just make changes to slide.js. in slide example 2 here you'll see the two animate functions are called:
animate(elementId, 20, 0, 0, 150, 250, null);
and
animate(elementId, 20, 0, 130, 150, 250, null);
to make it go right to left you just change the values to something like:
animate(elementId, 150, 0, 0, 300, 250, null);
and
animate(elementId, 0, 0, 150, 300, 250, null);
Thanks Eddie, I will give it a try. You are a good man :)
-DV
Great, but how to implement it in example four???
Thank you for this great script which is easy to use, but there is one problem. Size of box must be fixed. If I want to have non-fix height script doesn't work. Please think about that in future versions.
Thanks!
Hey guys this is really great, but i have a question which is if you want to have the window closed when you first open the page, how would you do that ? any idea?
@Mood We actually address that in another tutorial here.
Having an issue with the sliding panels 'jumping' as they slide. We pre-loading the images, but the browser seems to take it's time rendering the JS animation. Anyone had a similar issue and possibly some success in fixing it?
Thanks. It is really a nice piece of code with good explanation.
Awesome Coding!!!! helped me a lot!!!
Ok, so I am trying this code on Safari, IE, Chrome, and it doesn't work on any of the browsers. I'm talking the links provided do not work. Other javascript works fine so I am wondering what the issue is? Anybody else having an issue?
This is brilliant. I've been looking for something like this for ages. I have one question though... how would I go about introducing an ease in/out effect to the animation?
Is this even possible?
I have used this horizontally sliding method to increase/decrease width of div. On mouseover the animate function is called. the issue is that it flickers. can i get any help on this flickering.
I am also getting flickering on mouseover.
Morning.
Im a beginer.
Where should i put the 2nd code? i know where to put the 'position code' but i dont know where should i put the function code
Thank you
mykhairul90@yahoo.com
Has anyone figured out the flicker issue?
I am creating several example 2 panels vertically per page, how can I reset all panels with a final reset panel at the end? Thank you. These are great by the way.
Hello!
Great tutorial!
I struggle to slide an example 4 from right to left and move content downside as is explained hear:
http://www.switchonthecode.com/tutorials/javascript-tutorial-inline-sliding-panels
Please give me suggestion how to change this two to make them work.
Unfortunately I am beginner in this matter and example number 4 is most complicated. Any suggestions are very welcomed.
Piotr
Example number 2: How can I do to put one more on the side panel? How can I do to open the page with the panel closed and not open?
You can tell how to make the example 3 + to start ? Thanks
Hi, great job you guys did :-) I'd tried to put example2 into a menu but i cant figure out how I only get one slide open at the time.. i just copyed the code and changed the names.. but when i click at menu 1 at then menu 2 they are both open, do anybody knows how to do that only one menu appears at the time.. ?? plzz help.. Hope you know what I mean :-D
Nanna,
I was wondering if you ever figured out how to do this. I'm running into the same problem.
Thanks, Steve
How to make example4 slide from right to left?
Hi, I found the answer. http://forum.php.pl/index.php?showtopic=177313 It's in polish, but it's clear what to change. In
div id="exampleHeader4" change left:0px; to left:130px; . In functions slideUpStep1(), slideUpStep2(), slideDownStep1() change first 0 to 130. Voila!
Awesome.
Brilliant...!!! A shade would be more attractive and give a real effect.
Love the script! Is there a way to set it up so that it is at the bottom of a DIV and then expands up? I figured out how to make it go up but once it go up it covers the trigger to get it back down.
I'm so close... I've got multiple panels working in one page. But, one always is on top of the other regardless of the index value I set on it. But, that's not important. What I'm trying to figure out is if there's a way to have any other panels close when a new panel is open. If you'd like to see my code, the site is at "www.rwssites.com/vernon" Any help would be greatly appreciated.
Thanks, Steve
P.S. I love your CAPTCHA. Where can I get that?
Have you found your answer yet?
I'm trying to show/hide multiple objects in multiple directions and could use your solution to solve my own problem.
The think is that the button changes between 2 images onClick, and when boldly copying the code a couple of times, those images are duplicate the same amount of times...
How do I define the 'button image swap' only once while still animating 3 objects in 3 different directions?
Cheers, Chris
The flickering is an issue/bug in animate function.
add 2 lines: if(cLeft.toString()=='NaN'){cLeft = 0;} if(cTop.toString()=='NaN'){cTop = 0;}
or this 2: if(el.style.left == ''){cLeft=0;} if(el.style.top == ''){cTop=0;}
befour var totalFrames = 1;
Love the script. Am I missing something obvious? http://www.bigdeahl.com/Test3.html Why is text not disappearing in IE?
where can i put the javascript code in example 1
Great coding, In example 4, I have changed the height and width of the box. When loaded it works, once i shrink and expand it again it shows me a smaller box then before? Any help please?
Fantastic script! - Is there a way to delay the box appearing? so that it is not on display straight away?
I've just combined to codes from switchonthecode.com. The sliding code on this page and the fading in/out code here: http://www.switchonthecode.com/tutorials/javascript-tutorial-simple-fade-animation.
The javascript (insert in the head tag):
The body tag:
Tested in IE8, FFox 9.0.1, Safari 5.1
Great article, however I will suggest you do not have to make these absolute positioned elements. For elements without a defined height or width you can use clientWidth and clientHeight.
I'd like the content div to expand to fill the container, like "inherit" or "auto". Using those in the script breaks the script BIG-TIME, though. How to use non-number values in the animate() function?