Create a Simple, Intelligent Accordion Effect Using Prototype and Scriptaculous

Tutorial Details
  • Difficulty: Intermediate
  • Completion Time: 1-2 hours

We’ve all seen the “accordion” type effect used on many Web 2.0 sites; however, many accordion scripts are heavy, make poor use of the libraries they are based on, and don’t handle things like ensuring that the accordion maintains a consistent height. In this tutorial, we will use the Prototype and Scriptaculous libraries to create a lightweight, intelligent accordion.


Demo and Source Code



Step 1 - The Goal

Our objective is to create a lightweight accordion script based on the Prototype and Scriptaculous javascript libraries.
The accordion should:

  • Allow an unlimited number of accordion panes
  • Be completely styled by CSS
  • Be Unobtrusive—users without javascript turned on should see all of your accordion content
  • Be Light Weight—With relatively few lines of code; use event delegation to limit memory consumption.
  • Support any kind of content within the accordion
  • Ensure that when the content of each accordion pane changes, the height of the accordion remains constant to avoid
    the annoying “page bouncing” effect

This is a relatively advanced tutorial that assumes the reader has a reasonable knowledge of Javascript, CSS, HTML, Object-Oriented
programming, and a basic understanding of the Prototype and Scriptaculous libraries. However, complete source code is
available for you to study and the code is very simple to read and learn from if you are not familiar with the specific
libraries used.

Before we begin, you can see a working demonstration of the accordion in action.


Step 2 - Begin with Basic Markup

To begin, we will create some simple HTML markup for our accordion:

<div id="test-accordion" class="accordion">    
     <div class="accordion-toggle">Toggle 1</div>    
     <div class="accordion-content">Content 1</div>    
     <div class="accordion-toggle">Toggle 2</div>    
     <div class="accordion-content">Content 2</div>    
     <div class="accordion-toggle">Toggle 3</div>    
     <div class="accordion-content">Content 3</div>    
     <div class="accordion-toggle">Toggle 4</div>    
     <div class="accordion-content">Content 4</div>
</div>

Step 3 - Add Some Style

Next, we need to add some style around our accordion to make it look like an accordion. To begin with, we’ll do a first pass of basic styling and then add more when it’s all working. There are also some additional
styles that need to be included to ensure that the accordion will display correctly as it is animating.

div#test-accordion{
    margin: 10px;
    border: 1px solid #aaa;}

div.accordion {
    position: relative; /* required for bounding--works around a "peculiarity" in Prototype */
}

div.accordion-toggle{
    position: relative; /* required for effect */
    z-index: 10;		/* required for effect */
    background: #eee;   /* required for effect--can be anything except "transparent" */
    cursor: pointer;
}

div.accordion-toggle-active{
    background: #fff;
}

div.accordion-content{
    overflow: hidden;	/* required for effect */
    background: #aaa;
}

See the basic accordion with a simple stylesheet.

Step 4 - Create the Javascript Accordion Class

Prototype provides a wonderful framework for building classes in Javascript and we’ll use that functionality to build
our accordion class. This class will contain all the properties and methods of an accordion: the currently displayed
pane, the contents of the accordion, methods to expand and contract panes, and event handler methods to define what happens
when users take an action such as clicking. For now, we’ll set up the basic structure of the class as well as all the
properties and methods we’ll need:

var Accordion = Class.create({
    initialize: function(){
        this.accordion = null;           /* Stores a pointer to the the accordion element */
        this.contents = null;            /* Array of pointers to the headings and content panes of the accordion */
        this.options = null;             /* Allows user to define the names of the css classes */
        this.maxHeight = 0;              /* Stores the height of the tallest content pane */
        this.current = null;             /* Stores a pointer to the currently expanded content pane */
        this.toExpand = null;            /* Stores a pointer to the content pane to expand when a user clicks */
        this.isAnimating = false;        /* Keeps track of whether or not animation is currently running */

    },

    checkMaxHeight: function(){},         /* Determines the height of the tallest content pane */
    initialHide: function(){},            /* Hides the panes which are not displayed by default */
    attachInitialMaxHeight: function(){}, /* Ensures that the height of the first content pane matches the tallest */
    expand: function(el){},               /* Tells the animation function which elements to animate */
    animate: function(){},                /* Performs the actual animation of the accordion effect */
    handleClick: function(e){}            /* Determine where a user has clicked and act based on that click */

});

These are the basic methods and properties that we will need when building our accordion. Each of the next steps will
take you through building each method until we have a working accordion. If at any point during the tutorial you need
a quick refresher on what each method or property is for, you may use this heavily commented code as a reference.


Step 5 - Initialize: Get Things Started

Prototype classes have a special method called initalize() which is a constructor; this means it acts when the user
creates a new instance object of that class. For any accordion, we need to know 2 things before we begin:

  1. The id of the accordion element.
  2. The default starting position of the accordion (if anything other than the first position)

So, we will need to allow our constructor to accept those two parameters. Additionally, our constructor must:

  1. Retrieve and store the accordion and its contents as pointers to those elements
  2. Set the user defined options
  3. Set the current expanded element
  4. Determine the maximum height we will use as the height for all of our content panes and apply it
  5. Hide the content panes which are not shown by default
  6. Add an event listener to the accordion to watch user clicks.

Here is the code for our initialize() method:

initialize: function(id, defaultExpandedCount) {
    if(!$(id)) throw("Attempted to initalize accordion with id: "+ id + " which was not found.");
    this.accordion = $(id);
    this.options = {
        toggleClass: "accordion-toggle",
        toggleActive: "accordion-toggle-active",
        contentClass: "accordion-content"
    }
    this.contents = this.accordion.select('div.'+this.options.contentClass);
    this.isAnimating = false;
    this.maxHeight = 0;
    this.current = defaultExpandedCount ? this.contents[defaultExpandedCount-1] : this.contents[0];
    this.toExpand = null;

    this.checkMaxHeight();
    this.initialHide();
    this.attachInitialMaxHeight();

    var clickHandler =  this.clickHandler.bindAsEventListener(this);
    this.accordion.observe('click', clickHandler);
}

As you can see, we’ve set all of our properties to reasonable default values and called 3 methods to help get things set
up. Finally, we’ve attached the event handler to the accordion. Let’s create those three methods and the event handler.


Step 6 - Checking the Tallest Element

One of the requirements for our accordion is that it must scale so that even when the tallest content pane is expanded,
the overall accordion height will remain constant. To accomplish this goal, we will iterate through the content panes
determining which one is the tallest and set the maxHeight property accordingly:

checkMaxHeight: function() {
    for(var i=0; i<this.contents.length; i++) {
        if(this.contents[i].getHeight() > this.maxHeight) {
            this.maxHeight = this.contents[i].getHeight();
        }
    }
}

Step 7 - Hiding the Rest

Our accordion should only display the content pane specified as the current pane; all others should be hidden
by default. Additionally, we need to set these content pane’s height attribute to 0; this prevents the content pane from
briefly appearing fully expanded before properly animating.

initialHide: function(){
    for(var i=0; i<this.contents.length; i++){
        if(this.contents[i] != this.current) {
            this.contents[i].hide();
            this.contents[i].setStyle({height: 0});
        }
    }
}

Step 8 - Show the Default Content Pane

Now that we’ve hidden all but the default content pane, we need to make sure the default content pane displays correctly;
it’s heading should have the “active” style applied to it and it’s height should match the maxHeight property:

attachInitialMaxHeight: function() {
    this.current.previous('div.'+this.options.toggleClass).addClassName(this.options.toggleActive);
    if(this.current.getHeight() != this.maxHeight) this.current.setStyle({height: this.maxHeight+"px"});
}

Step 9 - Create the Event Handler

If you come from a traditional event handling background where we attach the event handler to each area we want clickable,
it may seem confusing that we are only attaching the handler to one element. We are using event
delegation
. For those of you unfamiliar with the subject, I have written a brief
overview of event delegation
which
will introduce you to the concept and why it is so important. That said, we need an intelligent event handler:

clickHandler: function(e) {
    var el = e.element();
    if(el.hasClassName(this.options.toggleClass) && !this.isAnimating) {
        this.expand(el);
    }
}

There are two parts to this function. First, we determine what was clicked. Then, we check to make sure that it was a
heading that was clicked and that no animation is currently running. If this is the case, we call the expand() method
to start the process of the accordion. The variable we pass to the expand() method is the heading on which the user clicked.


Step 10 - Start the Process

Now we can start the process of doing the accordion effect. We know the expand() method must take a parameter for the
element which was clicked. Using that parameter, the expand method determines which content pane to expand, and if it
is not already expanded, calls the animate() method to “do its magic!”

expand: function(el) {
    this.toExpand = el.next('div.'+this.options.contentClass);
    if(this.current != this.toExpand){
	    this.toExpand.show();
        this.animate();
    }
},

Step 11 - Doing the “Dirty Work”

At this point, all of the pieces are in place; we know which content pane is currently displayed, we know which heading
the user has clicked, and we know which content pane the user has requested to be shown. Now, we must create the accordion
animation. For this, we will create an animate() method that will use the Scriptaculous Effect.Parallel class to render
the two animations together; and the Effect.Scale class to change the size of each content pane. The animate method will
perform these steps:

  1. Create an array that will be used to store our Effect.Scale objects
  2. Collect the parameters to pass to the Effect.Scale constructor for the content pane that will be shown and create
    the object
  3. Add that object to our array
  4. Collect the parameters to pass to the Effect.Scale constructor for the content pane that will be hidden and create
    the object
  5. Add that object to our array
  6. Create the Effect.Parallel object that will run our Effect.Scale objects is sync.
  7. Tell our Accordion object that we are animating
  8. Run the animations
  9. Clean up any styles left behind
  10. Tell our Accordion object that we are finished animating
animate: function() {
    var effects = new Array();
    var options = {
        sync: true,
        scaleFrom: 0,
        scaleContent: false,
        transition: Effect.Transitions.sinoidal,
        scaleMode: {
            originalHeight: this.maxHeight,
            originalWidth: this.accordion.getWidth()
        },
        scaleX: false,
        scaleY: true
    };

    effects.push(new Effect.Scale(this.toExpand, 100, options));

    options = {
        sync: true,
        scaleContent: false,
        transition: Effect.Transitions.sinoidal,
        scaleX: false,
        scaleY: true
    };

    effects.push(new Effect.Scale(this.current, 0, options));

    new Effect.Parallel(effects, {
        duration: 0.5,
        fps: 35,
        queue: {
            position: 'end',
            scope: 'accordion'
        },
        beforeStart: function() {
            this.isAnimating = true;
            this.current.previous('div.'+this.options.toggleClass).removeClassName(this.options.toggleActive);
            this.toExpand.previous('div.'+this.options.toggleClass).addClassName(this.options.toggleActive);
        }.bind(this),
        afterFinish: function() {
            this.current.hide();
            this.toExpand.setStyle({ height: this.maxHeight+"px" });
            this.current = this.toExpand;
            this.isAnimating = false;
        }.bind(this)
    });
}

For a complete explanation of the option parameters we are passing to both the Effect.Scale and Effect.Parallel objects,
please see the Scriptaculous documentation.
The important aspects of the method are the beforeStart and afterFinish methods on our Effect.Parallel. The beforeStart
method tells the accordion that it is currently animating. This will prevent the event handler from attempting to start
any further changes so long as the animation is in progress. It also makes sure that the heading which was clicked is
given the “active” class name. The afterFinish method completely hides the content pane which had been previously displayed
(after it has disappeared due to the animation). It also ensures that the final height of the newly displayed content
pane is correct. Now that the swap is complete, it tells our accordion that the currently expanded content pane is the
one we have newly expanded and that the animation is complete.


Step 12 - Adding Some More Style

At this point we have a decent looking accordion, which you can see in action here. But with a little CSS we can make it all look much more spectactular. So first we create a quick Photoshop mockup so we have a rough idea of how it should all look. With that in mind, we’re going to need three images:

  1. A ‘logo’ image –
  2. A couple of nice background images – and

And here’s the revised CSS code:

body {
	padding: 130px 50px 50px 50px;
	background: #252422 url(../img/logo.gif) no-repeat;
	background-position: 60px 40px;
	font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Sans-serif;
	font-size: 11px;
	line-height: 18px;
}

div#test-accordion{
	border: 1px solid #343230;
	background-color: #21201f;
	padding: 10px;
}

div.accordion {
	position: relative; /* required for bounding */http://net.tutsplus.com/wp-admin/users.php
	width: 800px;
}

div.accordion-toggle{
	position: relative; /* required for effect */
	z-index: 10;		/* required for effect */
	background: #3f3c38 url(../img/off.jpg) repeat-x;
	background-position: bottom;
	color: #fff;
	cursor: pointer;
	margin-bottom: 1px;
	padding: 9px 14px 6px 14px;
	border-top: 1px solid #5d5852;
}

div.accordion-toggle:hover, div.accordion-toggle-active{
	background-image: url(../img/on.jpg);
	background-color: #6d493a;
	border-top: 1px solid #a06b55;
}

div.accordion-content{
	overflow: hidden;	/* required for effect */
	background: #302e2c;
	color: #c4bab1;
	border-bottom: 1px solid #000;
}

div.accordion-content p{
margin: 9px 24px 6px 24px;
}

As you can see here we’ve:

  1. Added some background styles around the page and the accordion class
  2. Given the accordion-toggle div a regular background color
  3. Set the accordion-toggle:hover and the active states to use the same reddish background

Step 13 - See It in Action

You can see the working demonstration here. You can also add your own CSS and images
to tailor the look to your site.

Download: accordion.js & accordion.css

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • George Burrell

    I have been reading through the comments here and there hasa been some interesting discussions. I am a novice when it comes to script languages but I agree with Brian… after all variety is the spice of life and all that jazz…

    Anyway for all of you that want to replicate this effect using jQuery, I have been able to use the source files (html & css) from here and follow the steps implement the same effect using jQuery:

    http://jquery.andreaseberhard.de/toggleElements/

    I hope its help to someone. Keep up the good work Nettuts!

  • kidd

    Is it possible to not show any content at first? So that you have to press some of them to show anything?

    When I tried I couldn’t find the place in the code to do this.

    I’ll be very happy if some of you can help me ;)

  • http://www.windows7themes.com Windows Themes

    i don’t know why, but here the transition effect (for example when i click on Contact Us) is quiet low. Any suggestions ?

  • Jonathan

    Hi, I commented out the checkmaxheight function, but I cant make the accordion work!! Please can someone explain how to deactivate the maxheight ?? Thanks!!

  • Florian

    Hi,

    I usually use jQuery for my JS work. So I do not have much
    know how about Prototype.
    As I need some additional styling in the accordion-toggle div,
    I add a extra span around my text. Unfortunately the span
    area doesn’t activate the toggle. Could you tell me how to
    add my span to the toggle function? thx

    Florian

  • Geoff

    This is a great tutorial, but I too would love to get it working without the maxHeight method. I’m working on it and will post back if I find a way around it.

  • http://rareview.com chuck

    very cool script, i was happy to find in the comments that the jerkiness was fixed. i also figured out that in the JS file if you change ‘click’ to ‘mouseover’ it works on mouseover; nice work! i do have a question that seems to be posted here a few times; can i have all of them closed when the page loads initially, rather than having the first one open?

  • Tritos

    Just me or does this not work in IE? Messing around with the effect in a concept for a site and the scripts don’t seem to work in IE.

  • Geoff

    Has anyone else checked this in IE 6 quirks mode? It’s really jumpy for some reason.

  • Geoff

    I’ve found a quick alternative to using the maxHeight method. Basically, in the animate function, just check the height of the contents of this.toExpand, and then apply that height, instead of maxHeight. my div contains a single so im getting that height. I also removed the reference to maxHeight at the end of the function, where it sets the height of this.toExpanb eg:

    animate: function() {
    var effects = new Array();
    var ul = this.toExpand.getElementsByTagName(“ul”);
    var h = ul[0].getHeight();
    var options = {
    sync: true,
    scaleFrom: 0,
    scaleContent: false,
    transition: Effect.Transitions.sinoidal,
    scaleMode: {
    originalHeight: h,
    originalWidth: this.accordion.getWidth()
    },
    scaleX: false,
    scaleY: true
    };
    effects.push(new Effect.Scale(this.toExpand, 100, options));

    options = {
    sync: true,
    scaleContent: false,
    transition: Effect.Transitions.sinoidal,
    scaleX: false,
    scaleY: true
    };

    effects.push(new Effect.Scale(this.current, 0, options));

    var myDuration = 0.4;

    new Effect.Parallel(effects, {
    duration: myDuration,
    fps: 35,
    queue: {
    position: ‘end’,
    scope: ‘accordion’
    },
    beforeStart: function() {
    this.isAnimating = true;
    this.current.previous(‘div.’+this.options.toggleClass).removeClassName(this.options.toggleActive);
    this.toExpand.previous(‘div.’+this.options.toggleClass).addClassName(this.options.toggleActive);
    }.bind(this),
    afterFinish: function() {
    this.current.hide();
    this.toExpand.setStyle({ height: “” });
    this.current = this.toExpand;
    this.isAnimating = false;
    }.bind(this)
    });
    }

    });

    I’m sure there’s much better ways of achieving this, but I needed a quick and easy solution.

  • Golabi

    How do you change the default starting position? I would like mine to start on the first one.

  • Frenchie

    I am very new at web design and I want to thank you for this wonderful code. I have adapted it to my website and it is working spendidly! You are a life saver!!!

  • http://nnta.us Ehab

    The effect works fine on this website, but when i downloaded the src files and tried it locally it jerks on all three browsers i’ve tested it on. I have’nt changed anything in it. I uploaded it to my own server and tested it there too and the same thing happens. Is the code used here different than the one we are downloading or what exactly is causing this to happen? Thanks..

  • Pingback: 75 useful Javascript Techniques | rafdesign

  • Pingback: Design Feeds » Blog Archive » 75 (Really) Useful JavaScript Techniques

  • Golabi

    Ehab,

    Look in the CSS file, there is something screwed up with the padding. I don’t remember what, but I had that problem and fixed it.

    I also figured out how to have it start out on the first tab. So I don’t need help for that anymore.

  • http://indyfromoz.wordpress.com indyfromoz

    Has anyone tried modifying the Accordion class to open more than one pane at a time? What I want to achieve is something like that done here – http://www.chrisesler.com/mootools/mootools-v1.2-accordion-extended.html. On startup, one more accordion panes may be open, the user may open/close any number of accordions while viewing the page. I understand there is a jQuery version here – http://jquery.andreaseberhard.de/toggleElements/ that does what I am after, but, I can’t use jQuery as I need prototype to use Lightview.

    If anyone has any ideas/suggestions, I shall really appreciate your help.

    Cheers,
    indyfromoz.

  • http://www.accesstoheaven.com zichzach

    Thanks voor the work it looks very good.

  • chuck

    in safari, sometimes the accordion loads and when you click each item, the box is not tall enough to fit all the content, so it gets cut off. a couple refreshes seem to fix this. i can’t reproduce in IE or FF. any ideas?

    • http://www.majksner.com Nikola

      If you are using images, put height in image tag. This was fixed my problem with safari.

  • http://www.jadgraphics.net/services.html Jad Graphics

    I am using something similar to this on my services page. http://www.jadgraphics.net/services.html
    But I am using Mootools… What seems to be better? Scriptaculous, jQuery, or Mootools?

  • Pingback: JavaScriptのテクメモ » Blog Archive » アコーディオンメニューその2

  • Karin

    I’m trying to use this script within a portlet for our intranet. It doesn’t seem to work. Works fine alone, but when I put it into the portlet, it doesn’t want to work. Any ideas?

  • http://www.darrenmcpherson.co.uk Gafroninja

    If you are going to use this accordion set up. DO NOT name your container id “accordion”. IE7 (not tested in IE6 or IE8) will throw up an error.

  • vespagirl

    This is just what I’m looking for, but even though it works great locally, when I try to integrate it into my site, I get an error: “Attempted to initialize accordion with id:test-accordion which was not found when calling method: [nsIDOMEventListener::HandleEvent…” In addition to prototype and scriptaculous files, I also have a bunch of YUI JS scripts, so I’m assuming that it maybe has something to do with the order of the files? I copy/pasted the HTML and CSS from the example so id “test-accordion” is definitely present in the DOM. Any ideas would be much appreciated.

    (I just noticed that Karin has the same question, above).

  • http://www.darrenmcpherson.co.uk Gafroninja

    Does this accordion support accordions within accordions?

  • Pingback: 75 (Really) Useful JavaScript Techniques | Evolution : weblog

  • Chanchal

    gr8 work…
    is it possible to have horizontal scroll also?? i m newbee to this

  • chilltron

    I’m trying to use transparent pngs for the titles as opposed to just plain ol’ text, however to get the accordion to work, I have to click anywhere on the bar that’s not part of the image. Not sure why I can’t click on the image to move the accordion. Anyone else try this?

    • http://artifexmedia.webatu.com artifexMedia

      Try setting the image as a background-image in the CSS instead of as an image?

  • Pingback: Getting Creative With Javascript: 15 Websites With Cool Slider and Scrollers | SulVision

  • c.kleier

    have someone solved the maxheight problem?

  • http://nettuts.com Barbarossa

    Hi!,

    i just dont understand how to add some more accordions with other contents on the same page, what do i have to do for this?

    thanks to all answerers, sorry, i’m a js_noob and dont know how to do this, have i to change something in the accordion.js file? or just to ad something new in the html page, f.example here:

    XYZ

    thanks and cheers from germany

  • http://www.blackinci.com/ blackinci

    Horizontal position ?

  • Pingback: Persistent Vertical Accordion with Prototype — Mimbles weblog

  • http://mimbles.net Edgar J. Suarez

    kudos for you!

    I’ve added a persistent functionality to keep the accordion expanded between requests.

    http://blog.mimbles.net/2008/11/19/persistent-vertical-accordion-with-prototype/

    Regards.

  • LP

    muy weno…!!

  • http://nettuts.com Barbarossa

    I use the same accordion effect like on this site, the same script and allways, i just cant find where i have to add that there are more than just one accordeon…so, what i need is, f.e.

    accordion_1
    accordion_2
    accordion_3

    accordion_10

    because if i make just a copy of the one accordeon f.e. under the on the html page it is complete open (the copy)…

    its a simple html page so i dont use any cms or anything else…thanks if somebody could help…sorry for the question, i know, it must be very simple, but i dont know how to do…

    greetings
    barbarossa, from germany

  • Jason

    I’d like to use different images as the nav element, instead of text, inside of each toggle div (where the demo has “Main”, “Why Use Us”, etc). So, I would have different nav or menu images inside each toggle div, including hover, active, and off states.

    I’ve tried to implement this myself, but have FAILED miserably. For instance, I tried adding individual images through additional css classes, but then the accordion just stops working.

    Can anyone help me with this?

  • Jason

    Ok – so I figured this out last night. Here’s what I did:

    I left the toggle div with the following styles:

    div.accordion-toggle{
    position: relative; /* required for effect */
    z-index: 10; /* required for effect */
    }

    I then gave each of the toggle divs I was working with an id, and applied the following styles:

    div#whatever{
    height: 40px;
    background: #grey;
    background-image:url(../img/whatever.jpg);
    background-repeat:no-repeat;
    background-position:bottom;
    color:#ffffff;
    cursor: pointer;
    }

    div#whatever:hover, div#whatever.accordion-toggle-active{
    background-image:url(../img/whatever.jpg);
    background-position:top;
    background-color:#grey;
    }

    So — doing this gives me the ability to use each individual toggle div as a menu choice with images instead of text. The divs now have ids, which I can style for inactive and hover states. The accordion-toggle class still applies, and drives the javascript effect.

    I found out through experimenting that the only way to style the active state for each toggle was to add the .accordion-toggle-active class to each specific id (i.e. — div#whatever.accordion-toggle-active{}). The effect just didn’t work otherwise.

    So now I can use this accordion and style each toggle with the different images for active, hover, and “off” states.

    Amazing what you can do if you tinker under the hood. Only took me three weeks of FAIL, because I’m such a noob.

    • Natalí Garcia

      Thanks so Much! ;D

    • http://www.creativityabounds.com.au/blog.html Jess @ Creativity Abounds

      Thanks Jason! Your three weeks saved me three weeks! My university course thanks you! I think you have officially grown out of the noob status and passed it onto me.

  • http://www.digitalcoffee.biz Holli

    I can’t seem to figure it out so can anyone tell me if there is a way to have all of the nav elements collapsed when you load the page?

  • http://www.70dvdgarden.co.cc Himel Khan

    nice interface,thnx.

  • http://www.methodologi.com Methodologi

    How can I adjust the height of the accordian content to auto adjust based on amount of content?

    Also is it possible to have the accordian load with all content closed?

  • http://www.mosik.info duomosik

    @chuck

    Yes I noticed this too. I think this is a webkit bug, as OmniWeb also has this bug. Yery annoying. It was no problem with Safari 3.0 but when updating to 3.1 it stopped behaving as expected. Look at my site: http://www.mosik.info and click on “More about JOHANN”, I’ve implemented this accordion there, even with different bg images for the headings.

    CITED COMMENT:
    in safari, sometimes the accordion loads and when you click each item, the box is not tall enough to fit all the content, so it gets cut off. a couple refreshes seem to fix this. i can’t reproduce in IE or FF. any ideas?

  • Agnostos

    Goodmorning,

    I would like to deactivate the accordion by clicking on an external button (which displays another type of content), how could I do it ? I tried to use the “deactivate” function in an onclick=”" but I don’t know what to target and I’m not sure it works like this.

    Excuse my English, I’m French ;)
    thank you.

  • Pingback: Getting Creative With Javascript: 15 Websites With Cool Slider and Scrollers

  • Pingback: デザインをする上で参考にしたサイトを挙げていくよ | xxxx7

  • Ronen

    @JPH,

    To modify it to open on the first heading area instead of the second, edit accordion.js, very last line:

    accordion = new Accordion(“test-accordion”, 2); <= Change the 2 to 1.

    That worked for me.

  • http://itsmattadams.extroverthost.com Matt

    Great tutorial, very easy to customize. I noticed that the Slimbox Plugin for wordpress prevents it from working.

  • Ehab

    how do you set the height to auto adjust to the content instead of always expanding to one maxHeight ??

  • Stuart

    Any chance of getting an update or patch for the latest versions of prototype and scriptaculous? Currently with the latest version each accordian open action flashes open all the divs and and each accordian close action flashes open all the divs.

    Thanks

  • Pingback: 大量折叠效果:酷站+免费下载+简单教程 | 前端观察