Simple jQuery Accordion tutorial

Today I will show you how you can do a small and very simple – yet powerful – accordion script.

The html code is very basic and consist in a standard DL/DT/DD structure:

Title
Content
Another title
Another content

Because is very possible to want to use this kind of accordion in many places, i did a small function:

function ntzAccordion(e) {
	$(e).find('dd').hide();
	$(e).find('dt').bind('mouseover click', function(){
		if($(e).find('dd').is(':animated') || $(this).next('dd').is(':visible')) {return false;}
			$(e).find('dt.opened').removeClass('opened');
			$(e).find('dd:visible').slideUp('slow');
			$(this).next('dd').slideDown('slow').end().addClass('opened');
	});
	$(e).find('.active').trigger('click');
};//ntzAccordion

Of course, we don’t forget to call this function on page load:

$().ready(function(){
	ntzAccordion($('.ntzAccordion')); // we call function with DL selector as parameter
});

Let’s see how is made

1. We find all DD’s inside of the e variable (which is $('.ntzAccordion')) and we hide them;

2. We bind mouse over and click events on DT. You can have both or none of them (you can use almost all events available on javascipt); Also, we will reffer to current DT as $(this);

3. If there is a DD which is hiding or showing in that moment, we return false. This way you can avoid odd behaviour and jumps;

3.1. Also, we check to see if the ‘victim’ (DD) is visible. Again, if this is visible, we return false to avoid repetitive close/open of DD;

4. We remove .opened class from all DT elements. We use this class to be able to add/change different style for different states of DT;

5. If there is an opened DD, we close it.

6. Because we use a structure like DT/DD, the next element right after DT is… a DD (doh!). We slide down that DD and we return back to DT (using .end()) and add the ‘opened’ class. It’s the exactly the one that we remove few steps above;

7. If you want to have a default element that is opened on page load, this line will do the trick: we trigger an event that is binded few lines above.

8. You sit back and enjoy :) 8)

Attention!

For some reasons that I think is a jQuery bug, you need to add one for those extra CSS for DD’s:

  • float:left;clear:left
  • position:relative
  • height:ZZpx;
  • width:ZZpx

If you don’t do this way and the DD have padding/margin, you will have a weird (and annoying too!) jump when the accordion expands or contract.

Also, don’t forget to view source on demo page ;)

Trhy it!

9 thoughts on “Simple jQuery Accordion tutorial

  1. Placing the accordion effect on a hover event is problematic, because of the fact that the active event areas might overlap during the animation, and trigger other unwanted events. E.g. expand the first box, then keep your mouse over the “Some menu” text, without moving it.

    Secondly, I noticed that during animations, hover events are randomly “skipped” in the elements above the current animation. E.g. expand the last box then move the mouse constantly upwards during that expansion animation – no other boxes expand in that timeframe.

    So there you have it – two solid reasons why the accordion should be set to a click event.

    P.S.

    The “jump jQuery bug” is actually not a bug. When resizing via animation, jQuery uses only the height of the elements, not their padding or margin. Inside the DD, you should add some other elements (such as Paragraphs) with margin or padding, to keep the animated DD without them.

  2. Hi Viorel, thanks for comment!

    I noticed that during animations, hover events are randomly “skipped” in the elements above the current animation.

    Is not a bug. There is a condition there to return false if there is anything animated. If you are not happy with this you are free to remove it, but i think this is better because you avoid the problems you exposed in your first paragraph :)

    Besides that, i specify that you can use any event available. I put hover only for demo :P

    The “jump jQuery bug” is actually not a bug. When resizing via animation, jQuery uses only the height of the elements, not their padding or margin. Inside the DD, you should add some other elements (such as Paragraphs) with margin or padding, to keep the animated DD without them.

    Well… Because padding directly affects the height and width of a box, i think that missing is a little bug :)

  3. About the first part of your reply, sorry for reading “diagonally” through your post and skipping directly to the example. That’s what I did and that’s why I missed that detail. :)

    As for padding and dimensions, the W3C DIV box model clearly differentiates the width, height, padding, margin, border and outline. jQuery has no way of resizing the padding and margin values proportionally with the height as it’s being animated, that’s why you shouldn’t use either for animated containers, but add padding or margins to elements inside them.

  4. As for padding and dimensions, the W3C DIV box model clearly differentiates the width, height, padding, margin, border and outline.

    Hmm… I didn’t know that :| Thanks!

Leave a Reply