Javascript And CSS Tutorial - Accordion Menus

Skill

Javascript And CSS Tutorial - Accordion Menus

Posted in:

A UI component common in many applications (and starting to become common on the web as well) is the accordion menu. A number of javascript libraries provide nice and simple accordion menus, but today we are going to take a look at how to build our own - because, well, that is what we do here at Switch On The Code!

Below, you can see the example that we are going to build today. It is a pretty simple animated accordion, where each menu is collapsible/expandable. You can have them all collapsed, or a single menu open. It should be pretty self-explanatory, so play around!

Accordion 1
I Am Accordion 1.
Accordion 2
I Am Accordion 2.
Accordion 3
I Am Accordion 3.
Accordion 4
I Am Accordion 4.
Accordion 5
I Am Accordion 5.

Ok, now that your done having fun with that example, lets take a look at how we actually do this. First, we have the html:

<div id="AccordionContainer" class="AccordionContainer">

  <div onclick="runAccordion(1);">
    <div class="AccordionTitle" onselectstart="return false;">
      Accordion 1
    </div>
  </div>
  <div id="Accordion1Content" class="AccordionContent">
    I Am Accordion 1.
  </div>

  <div onclick="runAccordion(2);">
    <div class="AccordionTitle" onselectstart="return false;">
      Accordion 2
    </div>
  </div>
  <div id="Accordion2Content" class="AccordionContent">
    I Am Accordion 2.
  </div>

  <div onclick="runAccordion(3);">
    <div class="AccordionTitle" onselectstart="return false;">
      Accordion 3
    </div>
  </div>
  <div id="Accordion3Content" class="AccordionContent">
    I Am Accordion 3.
  </div>

  <div onclick="runAccordion(4);">
    <div class="AccordionTitle" onselectstart="return false;">
      Accordion 4
    </div>
  </div>
  <div id="Accordion4Content" class="AccordionContent">
    I Am Accordion 4.
  </div>

  <div onclick="runAccordion(5);">
    <div class="AccordionTitle" onselectstart="return false;">
      Accordion 5
    </div>
  </div>
  <div id="Accordion5Content" class="AccordionContent">
    I Am Accordion 5.
  </div>

</div>

Essentially, we have an accordion container div, which holds each of the the accordion menus. Each menu is made up of a title div, and a content div. The title divs have an onclick attachment, which calls the javascript function runAccordion. As you can see, it takes one argument, which represents which menu was actually clicked on (in this case, the menus 1-5). Of course, this doesn't make a whole lot of sense unless we define the CSS classes referred to in this html:

.AccordionTitle, .AccordionContent, .AccordionContainer
{
  position:relative;
  width:200px;
}

.AccordionTitle
{
  height:20px;
  overflow:hidden;
  cursor:pointer;
  font-family:Arial;
  font-size:8pt;
  font-weight:bold;
  vertical-align:middle;
  text-align:center;
  background-repeat:repeat-x;
  display:table-cell;
  background-image:url('title_repeater.jpg');
  -moz-user-select:none;
}

.AccordionContent
{
  height:0px;
  overflow:auto;
  display:none;
}

.AccordionContainer
{
  border-top: solid 1px #C1C1C1;
  border-bottom: solid 1px #C1C1C1;
  border-left: solid 2px #C1C1C1;
  border-right: solid 2px #C1C1C1;
}

So the first chunk of css here applies to everything in the accordion. And it is here that you would change the width - modifying that value changes the entire accordion. Next, we have the style for the title blocks. A lot of stuff here, most of which is just making it look pretty. We use display:table-cell so that the vertical-align:middle style works (which is what aligns the title text in the center vertically). The -moz-user-select:none is to keep the text of the title from getting selected (in Firefox), which is useful because people will be clicking on the title bar. If you don't have that option, the title text will often get accidentally selected. The counterpart to this style for IE is the onselectstart="return false;" that we had up above in the html for each of the title divs.

The AccordionContent style is next, and is pretty simple. We hide it and give it a height of 0 pixels, because by default all AccordionContent divs are not displayed. We also set overflow equal to auto, which allows scroll bars to appear when the content is to big for the content div (useful for when the accordion menu is expanded, but the content still does not fit).

Finally, we have the AccordionContainer style, and all that does is set some borders, again mostly to make the menu look pretty.

Now, we can move onto the javascript, which is actually not that complicated. First, we have that runAccordion function referred to above, and some global variables:

var ContentHeight = 200;
var TimeToSlide = 250.0;

var openAccordion = '';

function runAccordion(index)
{
  var nID = "Accordion" + index + "Content";
  if(openAccordion == nID)
    nID = '';
   
  setTimeout("animate(" + new Date().getTime() + "," + TimeToSlide + ",'"
      + openAccordion + "','" + nID + "')", 33);
 
  openAccordion = nID;
}

So first we have a couple global variables. ContentHeight controls how tall a menu gets when opened - currently it is set to 200 pixels. TimeToSlide is the amount of time for the opening/closing animation, and it is currently set to 250 milliseconds. The opentAccordion variable holds the element id of the current open accordion menu. When there are none open, it is the empty string.

Now for the function runAccordion. The first thing we do here is transform the menu index passed in into the full element id, and hold it in the variable nID. If this is the currently open menu, then we are going to close it, and so nID gets set to the empty string (i.e., there is no new menu to open). The next thing we do is a setTimeout on a call to animate - a function which we will take a look at in a moment. And finally, we set the global openAccordion to the new open accordion, nID.

And here we have the animate function:

function animate(lastTick, timeLeft, closingId, openingId)
{  
  var curTick = new Date().getTime();
  var elapsedTicks = curTick - lastTick;
 
  var opening = (openingId == '') ? null : document.getElementById(openingId);
  var closing = (closingId == '') ? null : document.getElementById(closingId);
 
  if(timeLeft <= elapsedTicks)
  {
    if(opening != null)
      opening.style.height = ContentHeight + 'px';
   
    if(closing != null)
    {
      closing.style.display = 'none';
      closing.style.height = '0px';
    }
    return;
  }
 
  timeLeft -= elapsedTicks;
  var newClosedHeight = Math.round((timeLeft/TimeToSlide) * ContentHeight);

  if(opening != null)
  {
    if(opening.style.display != 'block')
      opening.style.display = 'block';
    opening.style.height = (ContentHeight - newClosedHeight) + 'px';
  }
 
  if(closing != null)
    closing.style.height = newClosedHeight + 'px';

  setTimeout("animate(" + curTick + "," + timeLeft + ",'"
      + closingId + "','" + openingId + "')", 33);
}

So the animate function takes 4 arguments - the last time the animation was updated, the amount of time left before the animation should complete, the element id of the closing menu, and the element id of the opening menu. The reason we care about time here is that the code always makes sure the animation completes in the amount of time specified in TimeToSlide. If we didn't do that, on slow computers the slide would have the potential to take much longer than TimeToSlide.

Because of all that, the first thing we do in the animation function is figure out how much time has passed since the last animation iteration. If that amount of time is greater than (or equal to) the amount of time left in the animation (as specified in timeLeft), we finish the animation. We do this by setting the opening menu (if there is an opening menu) to its full size, setting the size of the closing menu (if there is one) to 0 and making it invisible, and then returning out, thereby ending the animation.

If there is still time left in the animation, we calculate the ratio of time left to the total time in the animation, and multiply it by the the full menu height. This returns the new value for the height of the closing menu. Now, if there is a menu we are opening, we first make sure it is visible (because closed menus are initially invisible), and if it isn't we make it visible. Next we set the new height, which is full menu height minus the new height of the closing menu (this way as one menu closes, the other opens exactly in sync). Then, if there is a menu we are closing, we set its new height.

Finally, we do a new setTimeout call to animate, with the new values for the last time the animation was updated and the amount of time left in the animation.

And that is all that is needed to create an animated accordion menu using css and javascript! Here is a link to the javascript source file, and if you have any question or comments, feel free to leave them below.

Nick
11/02/2007 - 09:22

Is there anyway to get one of the accordians to Start opened up? I would like to make this be a type of a front page news story viewer.

reply

Julio
12/04/2007 - 10:39

Nick, to have accordion 1 open by default, add this class to your css:

 .AccordionOpen
{
  height:200px;
  overflow:auto;
}

and then alter the Accordion 1 html to represent this new class

reply

Julio
12/04/2007 - 10:41

oops, just change the class in the div that surrounds the text "I am Accordion 1." from AccordionContent to AccordionOpen

reply

Vlydon
04/16/2009 - 19:05

A better way to do it is to add:

onload="runAccordion(1)"

to the body tag.

This is better because if you do it using the previous method of changing the class, the first accordion doesn't close when you hit the next one. You have to hit it twice to hide the first. The onload method is in line better with the coding.

reply

Cssexpert
11/19/2007 - 04:19

Here is good tutorial about CSS: http://gohil.dharmesh.googlepages.com/css.html
Here is good tutorial about AJAX: http://gohil.dharmesh.googlepages.com/ajax.html

reply

Anne
12/06/2007 - 05:55

Hi, how to do it without a height specified? Thanks. :)

reply

Dave Porter
12/06/2007 - 20:44

Hi there,

Nice control.

I noticed that when opened the height of the opened area is fixed. How does one make the area dynamically high depending on the content.

Also I made my own image & the text within the image gets chopped off - any ideas on how to control this ?

Thanks Dave

reply

Tom S
12/11/2007 - 15:21

"I noticed that when opened the height of the opened area is fixed. How does one make the area dynamically high depending on the content."

I needed the same functionality but couldn't find a way to allow AccordionContent to expand that div, but I did find a way to override the ContentHeight variable in the js file by turning it off, and then create a height in a style sheet for each Accordion#Content div. It works, though I'm sure the developer can provide a more elegant solution. I'm showing changed parts only. Essentially, the changes are just commenting out the parts of the script that use the ContentHeight var.

---------
Change 1:

var ContentHeight = '';

-----------------------

Change 2:

if(timeLeft

reply

Tom S
12/11/2007 - 15:22

Woops. Not sure if I can post the length of code I did or whether it is in moderation. I'll check back and repost or post a link.
TS

reply

DanH
01/10/2008 - 10:04

Here is how I adjusted the sizing for the accordions...

in the javascript, make the first function look like this:

function runAccordion(index, AccHeight)
{
  ContentHeight = AccHeight;
  //...the rest stays the same

Then, simply when calling the runAccordion in your HTML, call it like this: runAccordion(1,250)...this will set the size of that accordion to 250.

Quick simple fix.

reply

The Tallest
12/07/2007 - 08:02

I hadn't checked on the comments on this tutorial in a while, and I see there are a lot of "feature requests" :P
I'll try and put together a more advanced accordion control that accommodates everyone's requests - so look for an article in the near future!

reply

Israel Meneses
12/09/2007 - 17:10

Awesome script!!

I'm looking forward to reading your next tutorial for the dynamic height control.

Also, I don't like how it shows the scroll bar when it opens up, can that be removed?

Thanks

Happy coding...

reply

Lance
12/11/2007 - 00:36

Thanks so very much for the terrific script. Not only do you provide it, but you explain what you did, how, and why. Very well done. If you want to see what I did with it (a little BSP here), visit www.mysteriesontv.com. I found that initially visitors to the site didn't understand how the menu worked despite a brief statement telling them what to do. After I modified the procedure a bit and displayed the first three entries of each category, people seemed to understand better. It's definitely an improvement over the list of over 100 titles I previously had listed there! Anyway, thanks again!

reply

Pau
12/13/2007 - 06:44

Very nice script, well explained, thanks for sharing such expirience.
I noticed, or believe so (correct me if I am wrong) that maybe ,just incase the computer is sooo slow that if it enters in the animate rountine for the first time past 250 ms already.
the display condition should be checked otherwise maybe the new open element might remain hidden.

Any ideas on how to make an evolution of this to a circular accordion? or an approximation for example a pentagonal design?
Cheers, Pau

reply

Rinku
12/20/2007 - 00:09

I am using accordion but it is working fine in IE7 but does not displays the div contents for the first title in Mozila unless I select other than first title option.After that if again first option is selected, it diplays the div contents.
I face this problem only in Firefox.

reply

LM
12/26/2007 - 13:00

Hi, thanks for the great tutorial! It works great. I would like for the first accordion to be open as a default. I tried Julio's suggestion above and even though it does work, the accordion then stays open even when you click on the others. Is there a fix for that?

Again, thank you!
LM

reply

Egeske
01/14/2008 - 19:01

Answer to the Accordion One being open! Ok, I was tried the css thing someone mentioned, of course that didnt work. So sometimes thinks are simpler than one could imagine. beating head on desk for 35mins thinking about this one.. then AhA! ... ok. when you click the accordion1 it runs, so instead in your body tag put onload="runAccordion(1)" ... works like a charm!!

reply

Egeske
01/14/2008 - 19:04

also... Fix to the scroll bar arrows showing up for a blink. Change your height to fit all your content then also change the add to your accordionContent tag, accordionTitle, overflow: hidden;

reply

Ejgeske
01/15/2008 - 06:24

Sorry about the bad english, my brain was frizzled. Now it is AM and i have coffee! woohoo!

1. To have the first Accordion open by default, put the javascript from your first accordion inside the "body" tag. (still keep the other one inside your first accordion tho, or it wont work when you try to close) so it will look like this:

body onload="runAccordion(1)"

2. To get rid of those flashing scroll bars use the tag "overflow: hidden" inside your css for your AccordionTitle and AccordionContent. You will have to resize your box to make sure it all shows when complete. But that isnt too hard.

Thanks to the creator of this Post, saved me alot of time trying to reverse engineer! Awesome and clean explanation, thanks again man!

reply

LM
01/23/2008 - 20:23

THANK YOU! Thank you so much for the updates ejgeske! Now it works exactly the way I wanted it to. Thanks again!

reply

Topher
01/10/2008 - 09:12

Great tutorial!
Quick question.

Is there a way to add a link on the top level (i.e Accordion 1) so that it goes to a sub page while opening the I am Accordion 1 submenu on the sub page?

reply

Charitha
01/10/2008 - 10:14

Thank you very much. This is very nice and simple to understand

reply

Swe Han
01/15/2008 - 02:10

I am new to javascript..
Just a contribution to make this accordion to make multiple-open concurrently by replacing the runAccordion() method..:)

var ContentHeight = 230;
var TimeToSlide = 250.0;
var openAccordions = new Array() ;

function runAccordion(index)
{
  var x;
  var nID = "Accordion" + index + "Content";
  var openAccordion=nID;
  var closeAccordion="";
  for(x in openAccordions)
  {
    if(openAccordions[x]==nID)
    {//already open
      openAccordion='';
      closeAccordion=nID;
      openAccordions.splice(x, 1);
      break;
    }
  }
 
  setTimeout("animate("
      + new Date().getTime() + "," + TimeToSlide + ",'"
      + closeAccordion + "','" + openAccordion + "')", 33);
 
  if(openAccordion!="")
    openAccordions[openAccordions.length]=openAccordion;
}

reply

Swe Han
01/15/2008 - 02:35

I use runAccordion(index, height) by DanH to set the custom height.

function runAccordion(index, AccHeight)
{
ContentHeight = AccHeight;
…the rest stays the same

Actually we can use offsetHeight to set the Actual Height of the div. For example on the html page..

Accordion 1

I Am Accordion 1.

It works! Actual height is set to the div. But the error here is that Opening has no slide-effect. The div appears immediately... though Closing works perfectly.

reply

Swe Han
01/15/2008 - 02:40

Sorry ..I include html codes in previous post and they disappear. What I wanted to say is.. in onclick=”" method of each div..

runAccordion(1, document.getElementById(’Accordion1Content’).offsetHeight);

runAccordion(2, document.getElementById(’Accordion2Content’).offsetHeight);
..etc.

reply

Tom
01/17/2008 - 11:07

changed from overflow: auto, to hidden. This removed the flashing in IE.

.AccordionContent
{
  height:0px;
  overflow: hidden;
  display:none;
}

reply

Nilmar Castro
02/25/2008 - 13:13

Hi! This is a great tutorial.
I have a question:
Is there a way to add a two or three levels of submenus inside?
If is, how to?
Thanks

reply

bart
08/25/2009 - 15:59

did u ever use this script with sublevels?

hope u can email me
bartbruins@hotmail.com

reply

Sab
03/14/2008 - 05:31

I made my own image & the text within the image gets chopped off, how you controll it?

reply

John
03/14/2008 - 14:00

Is there a place where the actual html portion is posted? I have set up the menu, but it operates very jerky. I must have something wrong, but I can not find it.

reply

Paul
03/26/2008 - 01:58

Hi,

I am new to web design and coding, so need a little help in how to put this all together.

Do I create separate css and js files or just lump it all together?
Would appreciate any help.

Thanks
Paul

reply

Solastyear
04/05/2008 - 14:09

hi there,

really top notch example. keep up the great work.

just wondering if there was a way of altering the code so clicking on one header does not automatically close the header that is currently open?

reply

Mofromthevilla
04/14/2008 - 14:12

Same question as solastyear. Can you get the menu to stay open until you click it to close? I'm brand new to javascript. I did add Swe Han's code into the original source file and it worked. However when i added more buttons/divs it broke and now I can't get it to work even with just 5 buttons can anyone help?

reply

Eddie Edwards
04/30/2008 - 22:35

How do you make sub-accordians within accordians. Or to put it better a submenu within a submen?

reply

Evden Eve
05/29/2008 - 08:54

also… Fix to the scroll bar arrows showing up for a blink.

reply

The Reddest
02/24/2009 - 15:14

I agree. I see the scrollbars flash for a second in Chrome and Safari, but not Firefox.

reply

Justin
05/29/2008 - 11:53

Hello. Great script! I was wondering how I can get each content area to dymanically grow when it is opened instead of having to use a set height that is set with "ContentHeight". If anyone can help me out that would be much appreciated. Thanks!

reply

Justin
06/02/2008 - 10:01

Figured it out:

var ContentHeight = 1;

if(opening != null)
  opening.style.height = 'auto';

reply

Billy
06/04/2009 - 16:26

Thanks Justin!!!

reply

Hit Kazan
06/03/2008 - 00:25

thanks you.. byeeee

reply

Poojitha
06/04/2008 - 03:33

Hi,
Good script,thanx it helped me a lot,but I have a question can I
implement drag stuff into this
Accordion,i.e I should be able to drag a row from somewhere outside
Accordion and put into it....
is it clear,pls help me out in this

Thanks
Poojitha

reply

Daves
06/09/2008 - 09:14

For those of you interested I've modified the script to overcome the issue of static-height divs. The heights now expand depending on my content.

I added a function to the page onload event that goes through the divs and captures into an array their true heights, before they are collapsed. Then, when I expand a div I modified the routine to get the ContentHeight from the array based on the index variable. If I can work out how to post up the code I'll do it...

reply

Mark
10/23/2008 - 21:12

daves... can you post your fix for the height issue?

It would be appreciated.

I've tried the other fix mentioned on this page by Justin, but it makes the open close transition very jerky.

Anyone else have a solution that works smoothly?

reply

Justin
06/12/2008 - 15:22

How can I have multiple content areas open at once. I tried the code above but it didn't seem to work. Thanks.

reply

Jesse
06/19/2008 - 19:16

I'm interested in knowing how to make the height of the divs dynamic rather than static. Awesome script!

reply

Ion
06/24/2008 - 07:22

Has anyone tried to use it with a master page? I can't make it work...
I have successfully made the accordion work on a standalone page, but when I throw the accordion on a master page and show a blank default page it falls apart; the accordion does render on the page but it doesn't expand or collapse

reply

Ion
06/24/2008 - 08:03

please help...

reply

Happyhardik
06/25/2008 - 12:50

Hi,

The effects seems to be great...

You will soon find it on my website, but I will try to convert it to horizontal sliding.. just thinking... :)

thanks for the share!!
happyhardik.

reply

Star22
06/25/2008 - 14:57

I also am looking to have a horizontal accordian, but I am too new at this to figure it out. Is there a spot in the CSS that would easily change to horizontal or will that take all new functions?

reply

Adam
07/07/2008 - 09:55

I'm trying to have the menu not display the section header of which ever section is active... hows I do this?

reply

Ben
07/25/2008 - 06:11

Thanks for the script works great is there a way I can make this so the menu is persisitant?

reply

Kapplesauce
07/28/2008 - 13:32

Great! I found it useful! However, is there a way to have background pictures in the accordions?

reply

Kapplesauce
07/28/2008 - 13:33

:) found it

reply

Bruce
07/31/2008 - 10:28

Does any one know how to add a accordion within an accordion???
Cheers

reply

Quy
08/06/2008 - 13:21

Thank you !

reply

Nisha Sharma
08/15/2008 - 03:27

hello i cant understand how to build accoidian code in my html page. please guide me

reply

Bhavya Gupta
09/22/2008 - 23:21

when i used the code given above in a while loop. all accordions got opened its not collapsed on one another how to fix the problem ???

this was the code i used...

reply

Rohit
10/16/2008 - 03:20

Great Code!!!
I have modified it a bit to include sub menu's inside each accordion. But was stuck with dynamic height of the accordion. Thanks to Justin.

The hack works absolutely brilliantly!!!

reply

sysguy
04/21/2009 - 14:34

Is it possible for you to either post or point to sample code to include submenus? It would be greatly appreciated.

reply

Mark
10/16/2008 - 17:07

I got this working fine as long as the js is in the head tag of the page. When I put the sc ript into an external file it doesn't work.

Do I need an onload event or something in the body tag? I tried
onload=”runAccordion()” in the body tag but that didn't work.

I'd like to get the script off the page as there are several pages that will have the menu.

reply

Rishu
10/24/2008 - 01:10

Thanks for this script,its good nd easy to understand

reply

Jenna
10/30/2008 - 20:04

would be nice for those of us who are not familiar with javascript if you could direct us where to place the code :\

reply

Sohail
11/02/2008 - 10:22

that was the best i have ever found.....but when i have embeded it my site i found a flaw....i donnt know why it is happening but when ever i hit the last menu button in IE6 (have not checked in IE7 yet), the whole div hide out and i donnt see anything

reply

Mike
11/06/2008 - 12:43

Thanks a lot for this great explanation. I needed to edit an accordion menu for our corporate site. I was lost until I found your page.

reply

Amoeba
12/10/2008 - 01:06

Thanks

reply

Me
12/10/2008 - 01:06

The Accordian menu is working great. Thanks for the wonderful code!
How to toggle images placed on div tags? I have a + symbol on div tag when closed it should change to - when opened and when clicked on another div tag it should become +

reply

Mobilya
12/14/2008 - 05:02

Thanks for this script.

reply

Prabhu
12/23/2008 - 09:47

Too good, very useful :)

reply

Albert
01/10/2009 - 09:36

Can I get the script with the auto size and the image placed on div tags (+ / -)?
This is cleanest impentation of an accordian out there. Thanks.

reply

lwnoble
02/17/2009 - 14:20

I am thrilled with this but does anyone know how to make the expanded tab look active and different from the others?

reply

cosinus
02/22/2009 - 10:35

thanks for your code
I used it to develop my site but i have a problem :
- how to transform your code to make it like apple Accodrion ?
I made 3 levels in your code :
- Menu
- Sub menu
- Links
and then I tried to keep (when I clic on links or sub menu) actif with another color (instead if i reload the page) like this script :
http://berndmatzner.de/jquery/hoveraccordion/index.php
but I failed !!!
Any help please ???

reply

Blue
02/24/2009 - 15:02

Sub-levels ?
Great menu. I'm trying to get sub-levels (sub accordions)to work, but my coding skills are too weak. (not worth posting my lame attempt)

If anyone has gotten sub-levels (accordions within the accordion) to work I would greatly appreciate it if you could post some code. You will be my hero, seriously.

It looks like people posted some code before but was taken out because not posted between language tags (see right side)

Thanks.

reply

Kempison
03/04/2009 - 09:23

Hi.

I would like to integrate the following functionality: a '-' or'+' will be displayed when the relative box is open/closed (i.e. replacing the 'Accordion N').

Here is an example from:
http://www.switchonthecode.com/tutorials/javascript-sliding-panels-using-generic-animation

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 = '^^^';
}
}

Also, if you're feeling really generous how can I add a fade-in 'onClick' to the content area? Like is found here:

http://www.switchonthecode.com/tutorials/javascript-tutorial-simple-fade-animation

Thanks in advance.

reply

Tracey Dey
04/07/2009 - 11:44

Hi, this script works beautifully, I just cut and pasted it into my page, how ever when I tried to create another version of it on the same page and clicked on the Title, it open the content of the First accordian. Is it possible to have 2 independently working Accordians on the same page?

Thanks

Tracey (newbie)

reply

Zak
04/13/2009 - 22:19

Hi,
great tutorial, got me trough a rough patch trying to use mootols accordion,
i have the same plea as Kempison...how to integrate animation with the fade effect?
is it possible to use Your simple fade effect? Or is it better to alter the animation function of accordion to accomplish this?

Thank You

reply

sysguy
04/21/2009 - 14:32

FWIW, I have found that by adding:

, ContentHeight=125;"

to the AccordionTitle line on the HTML side of things that I can individually control the sizes of the accordion that opens up.

<div><div class="AccordionTitle" onclick="runAccordion(291), ContentHeight=125;" onselectstart="return false;">Menu Title</div></div>

Now I'm really hoping to find an example of how to spawn accordions within accordions ... can anyone post or point to some sample code to do so?

reply

Adam
04/25/2009 - 21:34

Hi, I am using this script in my website and was wondering if theres a way to make it so one is always open to make it impossible to close all of them at once. Just wondering if its possible to implement into this script/

Thanks

Adam

reply

Anonymous
05/02/2009 - 04:16

i'cant understand it please explaine it in a simple way.

reply

Anonymous
05/07/2009 - 14:57

http://www.stickmanlabs.com/accordion/
Much more code, but more options and works

reply

Anonymous
05/16/2009 - 09:19

Hi, thanks for the code.. It has been very helpful. I have a question. I have changed the color of each header. They have all seperate image color behinde them which is done by using css. However,I would like to know if there is a way to give these headers onmouseover effect? I want to change these headers color when the mouse is over like a button.

Thank you very much for your help in advance..

reply

EvgenyUkraine
05/21/2009 - 11:23

Hi, I have fixed ContentHeight problem. Now you able to have flexible ContentHeight :)
(notify - page should has doctype!)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<body>
</body>

<script type="text/javascript">

var ContentHeight = 0;
var TimeToSlide = 200;
var openAccordion = '';


function runAccordion(index)
{
  var nID = "Accordion" + index + "Content";
  if(openAccordion == nID)
    nID = '';
   
  ContentHeight = document.getElementById("Accordion" + index + "Content"+"_").offsetHeight;
  setTimeout("animate(" + new Date().getTime() + "," + TimeToSlide + ",'"
      + openAccordion + "','" + nID + "')", 33);
 
  openAccordion = nID;
}

function animate(lastTick, timeLeft, closingId, openingId)
{  
  var curTick = new Date().getTime();
  var elapsedTicks = curTick - lastTick;
 
  var opening = (openingId == '') ? null : document.getElementById(openingId);
  var closing = (closingId == '') ? null : document.getElementById(closingId);
 

  if(timeLeft <= elapsedTicks)
  {
   
    if(opening != null)
            opening.style.height = 'auto';

   
    if(closing != null)
    {
      //closing.style.display = 'none';
      closing.style.height = '0px';
    }
    return;
  }
 
  timeLeft -= elapsedTicks;
  var newClosedHeight = Math.round((timeLeft/TimeToSlide) * ContentHeight);

  if(opening != null)
  {
    if(opening.style.display != 'block')
      opening.style.display = 'block';
    opening.style.height = (ContentHeight - newClosedHeight) + 'px';
  }
 
  if(closing != null)
    closing.style.height = newClosedHeight + 'px';

  setTimeout("animate(" + curTick + "," + timeLeft + ",'"
      + closingId + "','" + openingId + "')", 33);
}

</script>

<style type='text/css'>

    .AccordionTitle, .AccordionContent, .AccordionContainer
    {
        position: relative;
        width: 300px; /*changeble*/
    }
    .AccordionTitle
    {
        height: 20px; /*changeble*/
        overflow: hidden;
        cursor: pointer;
        font-family: Verdana; /*changeble*/
        font-size: 12px; /*changeble*/
        font-weight: normal; /*changeble*/
        vertical-align: middle; /*changeble*/
        text-align: center; /*changeble*/
        display: table-cell;
        -moz-user-select: none;
        border-top: none; /*changeble*/
        border-bottom: none; /*changeble*/
        border-left: none; /*changeble*/
        border-right: none; /*changeble*/
        background-color: Green;
        color: White;
    }
    .AccordionContent
    {
        height: 0px;
        overflow: hidden; /*display: none;  */
    }
    .AccordionContent_
    {
        height: auto;
    }
    .AccordionContainer
    {
        border-top: solid 1px #C1C1C1; /*changeble*/
        border-bottom: solid 1px #C1C1C1; /*changeble*/
        border-left: solid 1px #C1C1C1; /*changeble*/
        border-right: solid 1px #C1C1C1; /*changeble*/
    }
    .ContentTable
    {
        width: 100%;
        text-align: center;
        color: White;
    }
    .ContentCell
    {
        background-color: #666666;
    }
    .ContentTable a:link, a:visited
   
{
        color: White;
        text-decoration: none;
    }
    .ContentTable a:hover
   
{
        color: Yellow;
        text-decoration: none;
    }

</style>
<div id="AccordionContainer" class="AccordionContainer">
    <div onclick="runAccordion(1);">
        <div class="AccordionTitle" onselectstart="return false;">
            Accordion 1
        </div>

    </div>
    <div id="Accordion1Content" class="AccordionContent">
        <div id="Accordion1Content_" class="AccordionContent_">
            <table class="ContentTable" cellspacing="2" cellpadding="2">
                <tr>
                    <td class="ContentCell">
                        <a href='#'>Accordion 1</a>
                    </td>

                </tr>
                <tr>
                    <td class="ContentCell">
                        <a href='#'>Accordion 2</a>
                    </td>
                </tr>
                <tr>
                    <td class="ContentCell">

                        <a href='#'>Accordion 3</a>
                    </td>
                </tr>
            </table>
        </div>
    </div>
    <div onclick="runAccordion(2);">
        <div class="AccordionTitle" onselectstart="return false;">

            Accordion 2
        </div>
    </div>
    <div id="Accordion2Content" class="AccordionContent">
        <div id="Accordion2Content_" class="AccordionContent_">
            <a href='#'>Accordion 4</a>
        </div>
    </div>
    <div onclick="runAccordion(3);">

        <div class="AccordionTitle" onselectstart="return false;">
            Accordion 3
        </div>
    </div>
    <div id="Accordion3Content" class="AccordionContent">
        <div id="Accordion3Content_" class="AccordionContent_">
            <a href='#'>Accordion 5</a>
        </div>
    </div>

    <div onclick="runAccordion(4);">
        <div class="AccordionTitle" onselectstart="return false;">
            Accordion 4
        </div>
    </div>
    <div id="Accordion4Content" class="AccordionContent">
        <div id="Accordion4Content_" class="AccordionContent_">
            <a href='#'>Accordion 6</a>
        </div>

    </div>
    <div onclick="runAccordion(5);">
        <div class="AccordionTitle" onselectstart="return false;">
            Accordion 5
        </div>
    </div>
    <div id="Accordion5Content" class="AccordionContent">
        <div id="Accordion5Content_" class="AccordionContent_">
            <a href='#'>Accordion 7</a>

        </div>
    </div>
    <div class="AccordionTitle" onselectstart="return false;">
        <a href='http://google.com'>Accordion 6</a>
    </div>
</div>

</html>

reply

Kristin
09/11/2009 - 10:45

Thanks so much for this! It works beautifully!

reply

V
06/11/2009 - 11:34

Great code, this made my layout way cleaner.

reply

Chipley
07/28/2009 - 16:57

Cheers EvgenyUkraine,

This is awesome. Thanks so much for the contribution, you definitely get a gold star in my book. Excellent work!

reply

Irvin Rangel
08/19/2009 - 10:29

Hi guys, i would like to know how to make the accordion menu
in the opposite direction, i mean, when a click to the option menu it has to go up not go down like every accordion menu i've seen...

thanks for your help

reply

caveatashish
08/21/2009 - 10:07

Hi,

Nice one,

A small doubt, when I am opening the second menu, it will close the first menu and while closing the first menu a small vertical bar is being visible, how to Hide it.

reply

Anonymous
10/14/2009 - 12:45

if you mean the scrollbar do this:

In .AccordianContent

change to this:

.AccordionContent
{
  height:0px;
  overflow:hidden;
  display:none;
}

Justin
www.jcpsnowproductions.com - Web Design and Development

reply

Anonymous
10/21/2009 - 08:18

Has anyone gotten the "accordion within an accordion" to work. I have visited the site:

http://www.stickmanlabs.com/accordion/

but it looks like a whole new approach. I was hoping some just expanded on what is here.

Thanks

reply

jamel
11/01/2009 - 20:10

Thanx a lot its works beautifully, MERCI ;o)

reply

jscham
11/14/2009 - 15:08

Desperately trying to add 2 small images: 'arrowUp' and 'arrowDown' to the right of each accordion header text. These arrows should change dynamically depending on whether the accordion is open or closed.

Has anyone tried this?

I believe this will require modifications to the js, the css, and the html code. Am I right?

Can anyone point me in the right direction?

Thanks!

reply

Anonymous
11/15/2009 - 02:51

I used this code after customization. It works fine. Thank you for posting.

Javascript:
var ContentHeight = 1;
var TimeToSlide = 50.0;

var openAccordion = '';

function runAccordion(index)
{
var nID = "Accordion" + index + "Content";
if(openAccordion == nID)
nID = '';

setTimeout("animate(" + new Date().getTime() + "," + TimeToSlide + ",'"
+ openAccordion + "','" + nID + "')", 33);

openAccordion = nID;
}
function animate(lastTick, timeLeft, closingId, openingId)
{
var curTick = new Date().getTime();
var elapsedTicks = curTick - lastTick;

var opening = (openingId == '') ? null : document.getElementById(openingId);
var closing = (closingId == '') ? null : document.getElementById(closingId);

if(timeLeft <= elapsedTicks)
{
if(opening != null)
opening.style.height = 'auto';

if(closing != null)
{
closing.style.display = 'none';
closing.style.height = '0px';

}
return;
}

timeLeft -= elapsedTicks;
//var x=document.getElementById(Accordion1Content).style.height;
var newClosedHeight = Math.round((timeLeft/TimeToSlide) * ContentHeight);
//alert('banchod '+x);
if(opening != null)
{
if(opening.style.display != 'block')
opening.style.display = 'block';
opening.style.height = (ContentHeight - newClosedHeight) +'px';

}

if(closing != null)
closing.style.height = newClosedHeight + 'px';

setTimeout("animate(" + curTick + "," + timeLeft + ",'"
+ closingId + "','" + openingId + "')", 33);
}

.AccordionTitle
{
width:251px;
overflow:hidden;
cursor:pointer;
font-weight:bold;
background-repeat:repeat-x;
position:relative;
}

.AccordionContent
{
height:0px;
overflow:hidden;
display:none;
position:relative;
width:251px;
margin:0px; padding:0px;
background:#9EB96A;
height:auto;
}

CSS:
.AccordionContainer
{
position:relative;
}

reply

NSCSDesign
11/30/2009 - 14:09

This code is awesome, I can't figure out the container width, I still get this huge padding problem, is there anyway to fix it.

reply

Apostrophe Creative
01/16/2010 - 16:15

Awesome Tutorial! Thanks for taking the time to put it together! Quick Question! is it possible to keep certian panes open as a page changes.. I am using it as a menu so for example if they click about.. the pane slides down with all of the ABOUT menu items.. Is it possible to have it stay open based on what links are selected in about etc?

Hope this makes sense!

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.