Posted by The Reddest on 08/04/2008

9 comments
Skill

Javascript Tutorial - Inline Sliding Panels

Posted in:

We've written several different tutorials about sliding panels, and each time we get requests for different features and functionality. The first feature I addressed was starting the panels in an up position and having them slide down. Lately we've been getting comments about how to put the panels inline with the rest of the content. That is, when the panel expands or contracts, the rest of the page moves with them. That's what this tutorial will address today.

Just like with the other sliding panel tutorials, I'll be using version 2 of our generic animation code. You'll find using the generic animation code greatly reduces the complexity of creating sliding panels. You can download the generic animation javascript file here.

Below is what we're building today. It is a sliding panel that starts in the up position and moves the contents of the page when it is expanded or contracted. The panel has been tested in Firefox 3, IE 7, Opera 9.5, and Safari 3.1.

Click Me
Content

All right, let's look at how to build this thing. I'm basing the original panel off the previous sliding panel tutorial, so you might want to check that one out for a slightly more in-depth explanation. Let's begin with the HTML:

<div>
   <div id="exampleHeader"
      style="position:relative;
           width:150px;
           height:20px;
           top:0px;
           left:0px;
           background:#3b587a;
           text-align:center;
           color:#FFFFFF;
           z-index:1;"

      onclick="runAnimation(animationObject, this)">
     Click Me
   </div>
   <div id="examplePanel"
      style="position:relative;
           width:150px;
           height:1px;
           top:-1px;
           left:0px;
           background:#a6bbcd;
           overflow:hidden;
           z-index:0;">

     Content
   </div>
</div>

Typically you'd move all of that inline CSS into a file somewhere, but for simplicity and clarity, I just left it there. I start the panel with an outer div. In most cases you don't actually need this, but I like to group everything together inside a single tag. There are also some rare cases where you might actually be able to put this in a page where the header and the body could separate from each other if the containing div wasn't there. I then create two inner divs, one for the header and one for the body (the piece that will actually be doing the sliding).

In previous versions of the sliding panels, I relatively positioned the outer div and absolutely positioned the inner ones. That technique won't work if you want the browser to adjust page content based on the size of the body. Absolutely positioned divs typically 'float' on top of the page contents. So here I relatively positioned the inner divs, which will place them inline with the rest of the content.

I also had to do a pretty ugly workaround to make IE7 render the panels correctly. If the height of the body was set to 0, IE7 would not let the height go less than the height of the content. If the height was set to 1, everything worked well. This means I also had to set the position of the panel to -1 to hide the visible pixel behind the header. It's also why the header and body have a z index (to make sure the header is in front of the body).

Now on to the javascript:

var animationObject = new AnimationObject('examplePanel');
animationObject.AddFrame(new AnimationFrame(0, -1, 150, 130, 500));

function runAnimation(animation, header)
{
  if(header.expanded)
  {
    animation.RunBackward();
    header.expanded = false;
  }
  else
  {
    animation.RunForward();
    header.expanded = true;
  }
}

The javascript code changed very little from the previous version. The first thing I do is create an AnimationObject (which is defined in the generic animation code) and pass it the name of the element I want to animate. I then add a frame to it. The first two numbers are the position to which I want to animate the body, which in this case is the same position it's already at (I don't want to move it). The second two numbers are the body's new size, which is 150px wide and 130px tall. This means I will animate the body from a height of 1px to a height of 130px. The last argument is the time I want the animation to take - 500 milliseconds.

Whenever a header is clicked, the runAnimation function is called. It is passed the AnimationObject to run and the header element that was clicked. I simply check a flag that I added to the header element called expanded to see which way the animation should run and call the appropriate run method.

Putting all of the code together, you'll get something that looks like this:

<script type="text/javascript" src="SOTC-Inline_Sliding_Panels.js"></script>
<div>
   <div id="exampleHeader"
      style="position:relative;
           width:150px;
           height:20px;
           top:0px;
           left:0px;
           background:#3b587a;
           text-align:center;
           color:#FFFFFF;
           z-index:1;"

      onclick="runAnimation(animationObject, this)">
     Click Me
   </div>
   <div id="examplePanel"
      style="position:relative;
           width:150px;
           height:1px;
           top:-1px;
           left:0px;
           background:#a6bbcd;
           overflow:hidden;
           z-index:0;">

     Content
   </div>
</div>

<script type="text/javascript">
var animationObject = new AnimationObject('examplePanel');
animationObject.AddFrame(new AnimationFrame(0, -1, 150, 130, 500));

function runAnimation(animation, header)
{
  if(header.expanded)
  {
    animation.RunBackward();
    header.expanded = false;
  }
  else
  {
    animation.RunForward();
    header.expanded = true;
  }
}
</script>

Applying different styles to the containing div, like display and float, can get you much more flexibility in how the panel is integrated into the page, but I'll leave that up to you and your specific application. Hopefully this tutorial answers some of the questions we've received. And as always, questions and comments are welcome.

Robin
08/05/2008 - 12:16

Okay, I tried the IE 7 updated version for the sliding panels that are in the "up" position on page load. But what I really wanted was this. Thanks so much! You have saved my bacon for a client who wanted a replication of the functionality on the Brown University home page.

You have put so much effort into this whole sliding panel script, can I donate to your cause somewhere? E-mail me if I can.

Again, thanks - awesome work!

reply

Robin
08/05/2008 - 14:19

Last comment. I am using images, not text, and there is a 3px bottom margin on the header element in IE7. I have tried everything to get rid of it short of editing your animation.js file.

My goal is to slide an image down from the header image and they will be seamless when fully transitioned - creating a new total image.

Any ideas? If not, no worries. I am looking for other options.

It's still a great script and I'll use it somewhere.

reply

The Reddest
08/05/2008 - 15:58

Most elements in IE and FF have default padding and margin. You might try explicitly setting margin-bottom to 0 on whatever is in the header (although I'm sure you already tried this). Other than that, I don't have any more insight. Posting some example source code might help out (see here on how to post code in comments).

As far as donating, if you tell some friends to visit the site, that will work for me.

reply

Vladimir Y.
09/01/2008 - 12:49

I copied this code exactly as described and couldn't get the sliding panel to work? Sorry I am quite new to this and really wanted to add this function to my website. I've been trying various methods. Made the animation.js file, but it still did not work. However it works perfectly on your site, so I don't think its an imcompatibility issue.
Help appreciated. Sorry for the trouble.

reply

Vladimir Y.
09/01/2008 - 12:50

http://homepage.usask.ca/~vay216/Copy%20of%20sheets.html

sorry for the double post. here is the website.

This is the menu that I want to make sliding panels for:
http://homepage.usask.ca/~vay216/sheets.html

reply

The Reddest
09/01/2008 - 15:09

You're never actually creating the animation object that is passed into runAnimation. You have all of the html correct, but you need that snippet of javascript underneath the html.

I would recommend using your browser's Error Console to track issues like that down. Most browsers have one and they are indispensable for javascript development.

reply

gbsstudent09
01/31/2009 - 13:22

This code seems to be what I want, but I can't seem to get multiple instances of these working on the site page. My goal is to have 4 of these vertically stacked with different content within each one. I've gotten a single pane to work fine, but when I add a second one, that is the only pane that slides out now. I've tried changing variables within the page, but not the .js file. Any tips?

Thanks!

reply

The Reddest
01/31/2009 - 20:24

You should be able to put as many of these on the same page as you want. You'll have to make sure you give each one a different element id - "exampleHeader" and "examplePanel". I'd just stick a number at the end for each instance.

Then you'll have to change the Javascript to create an animation object for each element.

var animationObject = new AnimationObject('examplePanel');
animationObject.AddFrame(new AnimationFrame(0, -1, 150, 130, 500));

var animationObject2 = new AnimationObject('examplePanel2');
animationObject2.AddFrame(new AnimationFrame(0, -1, 150, 130, 500));

Lastly, in each header's onclick event, change it to run the correct animation object.

reply

Olivier
02/23/2009 - 23:42

Thank you very much for this great tutorial!
I managed to create some sliding panels and it worked very well.

My goal is to aligned 3 different panels next to each others and then have some images inside with some explanatory text.

I made some tests and the image shows up in Firefox but not IE6. I am also having some problems controlling the padding of the image and the text.

I am new to CSS and Javascript so this may seem easy to you.
Thank you very much in advance and sorry for the inconvenience!

Panel 2

My text here

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.