A few weeks ago I wrote about two ways we can achieve the "accordion menu" effect, and I promised to describe a third option. Well, this is it, Option 3. But first, here is a list of my other show-hide-toggle entries, as well as Jörn Zaefferer's accordion menu plug-in:

With this option #3, we start with all of the <div>s hidden. If we click on one of the headings, the following <div> will slide down. If we click on the same heading again, that <div> will slide back up. Clicking on on any heading will also hide all of the other <div>s — the ones that don't immediately follow it. Therefore, no more than one <div> can be open a a time.

To achieve this, we start by hiding all of the <div>s inside the first (:eq(0)) <div class="demo-show2">:

Option 3b: Zero or One, Queued Effects

Here we're going to keep the same rules about having either one or no <div>s visible at a time. But now we're going to queue the effects. In other words, we'll make the visible one slide up before the next one slides down.

But now things get a touch more complicated. We're going to set a couple variables—one for the next sibling of the clicked <h3> and one for all siblings of that next one, as long as they are visible <div>s:

So, now that we have the two variables, let's put them to use. We want to slide any visible sibling <div> up first and then toggle the next <div> using .slideToggle(). But we want this queued effect to occur only if there actually is a visible div. So, we'll use an if statement.

Hi Luis, by not behaving quite right in IE7, I assume you mean that there is a little bump at the end of the slide. I just fixed that by giving the paragraphs inside those <div> elements a style declaration of margin-top: 0. Thanks for the heads-up. Let me know if you see any other issues.

Finally a great explanation on those slick movement-options
Thanks a lot for making this, hehe.

There's only one little question in addition to your tutorial;
In your tutorial, the text shows up belów the buttons after you press it. Could you tell us how we could make a version where the text shows up abóve the button? So if you press that button, the button will slide down, showing the text that's been hidden "above" it.

@ziggy: I fixed both the IE6 and the Opera issue with a little modification to the CSS. IE6 needs the width to be defined for the h3, and Opera needs the cursor to be defined. here is the relevant CSS:

One little question if you don't mind;
I know that in JavaScript, you can set a fixed speed (don't ask me how though).
Is it possible to make the animation slower? I see you used 'fast'
as a tag in JavaScript... is that the speed-indicator?

Yeah, I set the animation to "fast" but you can set it to whatever you want, either by using a label ("fast" or "slow" or "normal") or by using a number. Numeric speeds are in milliseconds and don't take quotation marks.

So, if you wanted the .slideToggle() effect to take a full second, you would do this:.slideToggle(1000).

Hi guys, this isn't a comment on the post as such, but a tutorial suggestion. Could you write a tutorial about the use of "$(this)" within a callback and the right way to use it in different circumstances? I seem to always have trouble with understanding how it works and the proper syntax with which to use it.

For example, I was recently trying to replace text in an array, and even though I managed to figure it out (with great help from the mailing list), I still don't fully understand "$(this)".

Hey, Karl. I love the tutorial. It's really helped me a lot. My issue is that I'm using nested lists to structure my navigation and .siblings obviously won't work for that. Do you have any insight on how I might remedy this issue? I'm new to this so I don't know how to traverse the dom to find the elements I need to hide.

i got a list, each of its items must contain a div. in fact each of my "li class="titre"" tag corresponds to the "h3" tag of the first example and my own divs contained in each li have their proper "contenu_article" class. i'm a beginner at jquery and i'm trying to make this work

I'm not sure exactly what you're trying to show/hide. Still, I see a couple problems with the selector expression you're using. It looks like you're using HTML syntax ( e.g. li class="titre" ) instead of CSS syntax ( e.g. li.titre ). Switching your selectors to CSS syntax will go a long way towards getting your code to work. Also, you can remove the code that is specifically related to my example ( e.g. div.demo-show2 ).

If I'm understanding you correctly, you might want to try something like this:

I have a weird question. First let me say this code is great and almost what i am looking for.

I want to have images that when you mouse over it fades in a div on the right side of it and when mouse over the next one it fades out the previous and fades in the next div.

I have tried modifying this code but am having no luck.

Here is example HTML of the layout.

<table width="100%" border="0" cellspacing="0" cellpadding="0" id="ImageTable">
<tr>
<td class="images">
<A href="#"><IMG src="Image.jpg" border="0"></A>
<A href="#"><IMG src="Image.jpg" border="0"></A>
<A href="#"><IMG src="Image.jpg" border="0"></A>
</td>
<td class="divs">
<div>1 This is the box that will be shown and hidden and toggled at your whim.</div>
<div>2 This is the box that will be shown and hidden and toggled at your whim.</div>
<div>3 This is the box that will be shown and hidden and toggled at your whim.</div>
</td>
</tr>
</table>

I am so lost on how to get this to do this and can not tell you how much i would appreciate it if someone could help me out.

Thanks for looking at that Karl. It seems to work for me when I have the script in the head tag but not when I have it in an external .js file. Is there something I am missing? I don't know. I guess I'll just forget about the external file. Thanks again.

Not a problem. I'm not sure why it's not working for you when the code is in an external .js file, though. That shouldn't really have anything to do with it. I've moved my test file's script to an external file, and it's still working. Take another look.

A couple things to consider: Make sure you are including the jquery.js file before the other one. Also, it wouldn't hurt to double-check the path to the .js file, just in case there was a typo or something. Let me know what you discover!

I'm really not getting anywhere with this. I'm running this script on an Expression Engine site and it work great in firefox but ie (6 and 7) it works sometimes and then if you refresh it will just show all 3 boxes with content and nothing clickable. I can't see why it would work sometimes??? Unless EE isn't loading the full script.

I am running the jquery.js first. You are welcome to have a look if you want to as I'm not getting anywhere with it. http://www.mickykelleher.com/golf/ (The site is a work in progress)

Hi, as i am viewing the above demos of after a tutorials, they are shuttering in the Firefox 2.0.3
But when i view the same in IE6.0 it slides beautifully. In FF 2.0.3 it slides after a bit of shutter.

Try removing or diminusing, in the CSS code, the top and bottom padding of demo-show2.div. Include that height in an old html variant (a table with a row of the same hight for example). I hope I understood your question write.

I have a question. If i want the section I click on to become the top, how do I do this? I was curious since after i used it and my sections were about 4 paragraphs longer it became annoying to scroll to the correct section each time. I was wondering if there's a way to expand/collapse, as well as scroll to the proper section all at once. Thanks.

Karl: not sure how Interface's .Scrollto() would help with this. Basically I need to know how I can use the jquery/accordion madness to open an anchor with an id attribute. For instance: Title2, or Title1 (your demo with some added markup). I've been searching jquery docs for anchor and target info, but have been unable to find anything. Maybe I'm looking at the wrong stuff?

Oh, sorry huphtur. Totally misread your question. I just took another look at the moo.fx page that you linked to, and, I have to say, I don't get why they're using those anchors in the way that they are. For example, they have <a href="whatsnew">what's new</a>, but they don't have anything on the page with id="whatsnew" or even an old-school anchor like <a name="whatsnew"></a>. It adds the hash to the URL, but since the anchors don't exist on the page, clicking on those headings keeps adding unnecessarily to the history, making for terrible "back button" navigation.

Anyway, Klaus Hartl's Tabs plugin does a really nice job of using anchors the right way, tracking history so that the back button will actually do something. If you check that one out, I'm sure you'll be able to glean some really useful stuff from it. It's not the straightforward accordion, but it works on the same principle.

I realize this is the second time I've urged you to take a look at another plugin to find the solution, but I'm really not trying to avoid helping you. Really!

On the apple site they have their own version of what appears to be an accordion type menu. It's on the right and left side when you mouseover. I'm sure you've seen it already.

My question: Have you been able to mimic this effect with jQuery. On every jQuery accordion i've seen and made, the bottom will always make some sort of bumping motion. Depending on the speed it might be a big bump or a small bump. I've been able to minimize it, but never get rid of it like Apple has. Any ideas? I probably need an entirely different approach.

Hi Justin,
I'm not seeing the "bumping motion" in the examples above for this blog entry. I might not be understanding what you mean by "bumping," though. One thing you might want to try is setting a height for the containing element like Apple does. That way, everything below it will stay in the same spot even during the sliding animations. Hope that helps point you in the right direction. If this doesn't make sense or doesn't work for you, let me know and I'll try to put up a demo over the weekend.

K. Bumping may have been a bad description. It's also more noticeable when you have more than 3 tabs. I will try to describe it better:

In the last example on this page before these comments, if Title 1 is open and i click Title 2, then title 3 moves up with it. If you set the show and hide to the same speed, then title 3 will just make a small move down and up, a "bump" if you will. You can see it in my example here:

On the apple page, if i have the first tab open and mouseover the second tab, the third tab does not move at all. That's the effect i'm looking for. It loosk more solid. I have used javascript to set heights on the container and the tabs themselves, and this stops the tabs from interfering with the rest of the page, however the tabs themselves make these jumps.

Ah! I definitely see what you mean now. I don't know what could be causing this, but if you post the question to the jQuery Google Group, maybe someone who is more familiar with the fx.js component of the jQuery source code could provide a solution. Otherwise, this could be a bug that should be logged n Trac on the jquery.com. But posting the question to the Google Group is definitely the first step. Make sure you provide the URL, too. That was really helpful for seeing what the problem is.

I know someone else asked this but I can't find the solution anywhere.

How can I have the class of an h3 change when you click on it, and then revert to normal when you either

1. click on it again, or
2. click on a different h3?

I tried the following:

$('this').toggleClass('active');

inside the conditional statement of your "//queued showing and hiding" example, but I quickly discovered that I have no clue what I am doing.The class changes but stays that way when I click on other h3's

Hey Bobby, Congratulations! I'm glad I didn't see your posts until now. It's so much more satisfying to figure these things out on your own, isn't it? Don't hesitate to ask for help, though, if you run into any further snags.

I'm trying to accomplish something similar, but haven't figured out how to add Bobby's idead to my set up.

I'm curently using this html:

Services

For the web

Web Design
Squared Eye is known for our attention to detail, our love of all things easy to use, and the way we can take your needs and find a web solution for them.

Web Development
If you need your website to live and breath — to do more than just be an online brochure — Squared Eye can take your site to the next level, integrating anything from e-commerce to video and a myriad of helpful technologies in-between.

Hi Matt,
My pleasure. Doesn't matter if the unordered list is nested, just that the h4 within each li has only one sibling -- a p. So, you need to go up from the clicked h4 to its li, then select all of that li's sibling lis, and within those find all ps and slide them up.

About the addClass(), what you have should work. I peeked at your code and didn't see you doing that. If you wanna shoot the whole script to me so I can take a look at it, feel free to send it through the contact form.

It uses moo.tools.js and a clever http:// call in a file called core.js and another named core.ajax.js . The scrolling effect seems to be buried in the last third of the page:
... "&contact=1&ajax=1" load_content('contact_div', SITE_ROOT, poststr)...

I can get everything to work except for the sliding action of each "page" even though all the code is on the index page itself. Just looking for a tip on how the core.js interacts with the info on the index page.

I just thought this would be a good question for the Jscript / JAVAscript gurus.

Hi Caleb, I'm guessing now that you want a separate element that, when clicked, will open all of the hidden items, but I'm not sure because I can't see anything on that page that you might want to bind to that behavior.

The first thing I'd do is change all those span elements to divs, because they contain paragraphs. spans should only contain inline elements.

Hey all
Great tutorial...new to jquery but am loving it switch from mootools and not looking back. i am having one problem though. i have multiple instances of a div with the content i want to hide at first and multiple instances of a click handle. the problem is with only showing one div at a time... the way it works now is that the user can click multiple show/hide links and the previous one will still show itself until you toggle it. here is the html:

thank you very much it seemed to work.....but it kinda caused an adverse effect. for some reason it is controlling the "rate this feed" div now too. trying to figure it out....thanks a lot for the help. here is what ive got so far http://celebrityfed.com/v-1-3c.php

When using the latest version available at jQuery.com I get a bump at the end of the animation, but it works fine in your examples. So I tried using your jquery.js file which solved my problem, but instead something else stopped working as intended: when you click an already expanded item I dont want anything to happen. For some reason when using your version of the jquery.js the menu closes and expands if you click an expanded link.

Here are two links to demonstrate what I mean:

The latest version available from jQuery.com. Expanded menu does not re-expand when clicked but theres a bump at the end of the animation in IE 6:
• my jquery.js file

Your file. Works fine in IE 6, but an already expanded menu closes and exapands when clicked:
• your jquery.js-file

The relevant code is the first line in the function: $("dd").click(function()

How do I do to make a sublink appear selected (CSS) when I click it? It should apen another page in another frame... but the menu shoud be selected after it. I already tryed the `p` parameter in the URL but didn´ work. Please I need help.. Thanks in advance.

Please, how can I make visible my hidden element (with an id="xyz") when it matches current page pathname - (.../page.htm#xyz)? (I want to open and scroll to it from a link on the same or another page).

would it be possible to change the heading on click?
say for example, on the corner of the header i have 'expand', once i click on it, the contents display while at the same time, the word 'expand' changes to contract. im guessing the 'expand' could be just an image instead if that would make things easier?

Hi Caleb,
I don't see the text in your example page (though I do see it in the screenshot). The principle will be the same as I described in comment 83, but the selector expression will just be a little different. For example, you could put a <span> inside the <h4> with the "expand" text in it, right before the other text and float it right. Then you can just change the text on clicking the <h4> the same way I showed in comment 83, except that, instead of this:

I'm at a total loss here. My keyboard is getting covered with the hair I've been ripping from my skull trying to get this to work. Tried to modify each of your show/hide related examples but to no avail.

Hi Sean,
I don't have time to write the whole script out for you, but I'm guessing that the problem you're having involves identifying the correct div to show and hide when you click on one of those links. Try pasting this into your script file. Then you can go through and replace the logic of what gets shown and hidden when by looking at the example script in this entry:

Thank you very much for your hard work. I am primarily a graphic designer and have been getting into web in the last year, but have been using a programmer. I know HTML and CSS, but have been trying to learn some javascript and this is the best source that I have found.

I am new at this so please be patient, but is there a way to keep the menu open when I click on links. For example, if I open "Video Solutions" and I click on a link the accordion closes. I can separate the menu using php, but it still will continue to close because it is reloading the menu. Any advise?

Hi Dustin,
I'm not sure what you're referring to when you write "rollover/click text swaps." It could mean any of a number of things. Can you point me to any examples of this sort of thing on another site that I can look at? Maybe then I can write up a tutorial on how to do it.

Great stuff! I'm desperate for a slight amend! I would like to have a different CSS style for the title you are currently looking at, ie if I'm looking at "Title 2" contents I want the Title 2 heading to have a different text colour.

I've managed to add a class quite easily but I can't find the place to remove it! I've tried adding a toggle function but it's not happening! Can anyone help?

Hi Mark, I'll have to look at your page to see what is going on. The addClass should not be changing any of the h4 elements except the one that you click on. That's why you're using $(this) instead of $('h4') for the addClass.

Sorry, my mistake, I should have been much clearer. When I click on the title I'm currently reading, to close it down (almost as if I've refreshed the page and reset everything) the current title doesn't loose it's "on" class. It's a little pedantic but thought there might be a solution. To be honest, I was kind of getting us to the class staying on - it gives me a nice "visited" link sort of vibe!

On an aside, if your looking for tutorial subject matter I'd love to see a jquery version of this: Ajax Sortables! I haven't seen any jquery tuts that allow you to dynamically update databases.

I am using the accordion as part of a vertical navigation with h2 as header and nested ul as the submenue that I want to hide. The toggle works fine, but somehow the hiding of the siblings doesn't work.
Does anyone has an idea why?!?

I'm glad you found the tutorial helpful, and it's nice to see that you got something working for your client. Yeah, I probably should have pointed you to a more obvious example of the plugin. Next time.

I'm playing with this to make some changes to my personal portfolio site and am wondering what I need to do to make the first set of content show when a user lands on the page. For this example, I would want the content under Title 1 to be showing when the user lands on the url.

What a great thread! A wonderful community this is! Someone else created this accordion menu and I can't seem to work out adding the functionality I need. Maybe someone could give me some help.

I have this accordion menu that functions properly, though it reloads when a link is clicked (page referesh) so the accordion is closed instead of re-opening the menu panel with the active link. Similar to Dustin's problem above. Here it is if anyone has a few minutes to share:

Unfortunately, there is some missing information that I need to see in order to help you. You use the .hoverAccordion() method, but I'm not sure what that is supposed to do. Also, I don't see you binding a click handler to any of the links. At the very least, you should have the clicks return false on any links that you don't want to refresh the page or take you to another page. One more thing: it probably makes sense to declare your variables (doc, split, finder, etc.) using "var" to be sure you won't run into any naming collisions.

After taking a second glance at your code and your description of what you want to have happen, I think the problem lies here:

activateitem: 'panel',

With this "activateitem" option, you're now saying that it should match the string "panel." But since you have a bunch of lines of code before it which try to set the value of the panel variable, I'm guessing you want to remove the quotation marks:

About the problem with the active section's menu items not showing, your best bet is probably to contact the developer of the hoverAccordion plugin. That activateitem option should be working with panel, as far as I can see. You should, however, remove the last line in the code now -- $(panel).show('slow');

Here is an alternative way that you can get the active section's items to show, if it just won't work through the plugin's option:

Karl, great script! But I’m having visual glitches with IE7. It appears that the height of the content makes difference. Your demo works fine until I remove some “lorem…” content, in fact everything is smooth if there’s some text that fills up the div for more than 3 lines, less than that it jerks when closing. Just before final closing (last frame?) in animating I see the full open position and then it closes. I wonder why is that. Perhaps some magical css extra will solve the issue?

I can't recall offhand what causes this sort of thing, but I think it might have to do with top/bottom padding or margin. You might want to try zeroing out those properties and trying again to see if that fixes the problem.

I played around with every height affecting property that popped into my mind (height, line-height, margin, padding) but nothing seemed to fix the problem. But then I did some research on Animate effect in Jquery library itself. It has 2 methods of “easing” i.e. how the smoothness of the anim is handled – linear and swing, latter being the default one as far as I understand. And this is where things go wrong I think. So I tried to force slideToggle and slideUp to use linear instead. I achieved this with the following code:

I’m not sure why it works though as the second parameter, like manual and demos describe is for callback (function to be executed whenever the animation completes). Ok still, this didn’t solve problems yet – had to test with different speeds to get the right smoothness and in my case 200 seemed ok speed. So in conclusion – managed to make it work for me but I’m not exactly sure how and why it works

Your question is a little off topic. Anyway, you really need server-side code to communicate with the database. You can then use jQuery's ajax methods to request that code. Check out the ajax methods on the official documentation site for more information.

Hi, great tut! Just a question, let's say I have 3 links first and then 3 containers that I need to show and hide, obviously using sibling won't help since thecontainers are not sitting next to the links, what should a do in this case? Thanks!

Hi, great tut! Just a question, let's say I have 3 links first and then 3 containers that I need to show and hide, obviously using sibling won't help since the containers are not sitting next to the links, what should a do in this case? Should I use tabs instead of this approach? Thanks!

If you check the aforementioned URL, the accordian works but after being clicked the layers don't hold their positoin and overlap some. I am assuming this is a problem with the div style attributes, can you offer some advice? Thanks in advance-
-Ryan

The problem is that all the divs inside each container div are floated, so they are outside the flow of the document. Adding clear: all; to .menu {} should do the trick. Let me know if that doesn't solve the issue for you.

Hi Karl-
Thanks for the response. I tried your suggestion and had no luck. Any other ideas? When I set the float:left attribute it fixes the current problem but the collapse no longer works right. Any ideas? Thanks in advance-
-Ryan

Hmm. I didn't suggest using float:left. I just looked at your page again, but I didn't see clear:all; applied to the "menubar" class in the styles. Please do that, and if it still isn't working, I'll examine it more carefully.

I am quite new to the jQuery and I am using it for my main menu navigation, the question i have is when i go to a new page from a link on the menu how do i keep the state (selected menu displayed in the accordion). Is there a simple way to do this ?

Hi there,
Sure it's possible. It's unclear to me which div(s) you want to bind the click event to and which one(s) you want to hide and show. Do you want the "description" div to appear when you click the "class" div? When you click the "status" div? Both? Neither? I'm confused.

However you have it set up, I think the trick for you will be to use a combination of child/parent selectors and the this keyword.

Very nice script..however i've encountered a problem though. It basically 'jumps'. So the content appears, then jumps up about 10 pixels. When you click to close, it jumps down the same amount, the new content appears and same thing happens.

Turns out it happens when you include p tags inside the divs that get shown/hidden.

To solve this problem, you have to make sure those p tags are given margin and padding of 0px in your css. Number of ways to do this, but best to give each div your showing/hiding the same class (such as 'showhidecont') and put this in your css

Karl,
some great tutorials on jquery here, thanks a lot. I'm very interested in your (Tab Example). I was wondering how I would go about hiding all the panels (instead of having one automatically showing) and having them slide up and down on-tab-click like this accordion example? i.e. zero or one.
-Philip

Anyone ever use this application with an unordered list and sub menus? I have a client that wants to have a vertical navigation able to reveal sub navigation for each section on rollover. I realize i could set it up as individual s but would like to maintain my

Hi,
every time I use slidetoogle, the content wich is hidden just before slideing shows up in a milisecond completly, hides back, then he slides down, and when I click to slideup, he slide just fine, and when he rich end, he do this reset - streching thig again in milisecond, and then it hides again.

I dont get it, because I am using examples code above, but when I trying it here on your page everything is just fine, so I suppouse this hasnt nothing to do with IE6 wich I am useing.

If it works here but not on your page, I guess the first thing to do would be to see what the differences are between the two pages. You might want to start by looking at the CSS. If you'd like some help, post a link to the page in question.

Hey guys, I'm new to this... I have put together the Accordian panel, but am having problems with one thing. I really want to have an additional heading within each panel. For some reason the as soon as I add a subhead and add a or or

etc. the panel will not hide or work for that manor. Is there any way to style an additional heading (other than the standard H3). Thanks for any light you can shed on this.

This code/post has been incredibly helpful. There's a good variation on this here (scroll to example 4) that expands on this code to include a class toggler and more.

I do have a question. Would it be possible to do an "upside-down" version of this accordion? For instance, if I clicked on "Title 2", Title 1 & 2 would shift up, Title 2's div would reveal and also shift up, and Title 3 would remain stationery during this whole fiasco. I've tried experimenting and Googling, but no such luck (plus I'm not even sure what to use as search terms. Upside-down accordion script? Bottom align accordion script?). Part of my brain refuses doesn't believe the internet will even allow this to work.

If you know of any solutions, scripts, or even any initial hints of an idea, that would be most helpful.

I have a non accordian question.
i’m trying to use the following code and i want to hide a div “.nextblock” when i click any where on the page, except on that div. But this is not working. It hides the block even if i click on the div “.nextblock”.

I have failed to implement the above for the following... on clicking the word "change" it should toggle the 'secondchild'... I can do this one 'firstdiv' but then it goes on the next 'seconddiv'. How can I implement the above method with different parents...

Sorry the was not enclosed in pre...
I have failed to implement the above for the following... on clicking the word "change" it should toggle the 'secondchild'... I can do this one 'firstdiv' but then it goes on the next 'seconddiv'. How can I implement the above method with different parents...