Slide out and drawer effect

6Jan

Background

John Resig, author of jQuery demonstrated how easy is create this simple slide aka drawer aka accordion effect during @media Ajax 2007 - it also makes for a great introduction to jQuery.

The effect is commonly known as an 'accordion' and it's usually used to slide up, or down blocks of content to expose new blocks.

Apple downloads drawer sample

The Apple web site is a great demonstration of this effect in action, where the mouse settles on the title of the 'section' and the associated links are exposed. What makes this effect particularly cool, is that the drawers maintain a fixed height and slide between restricted area.

This tutorial will walk through how to create your own simple plugin, and then replicate the Apple downloads drawers using the very excellent Accordion plugin.

Markup

Since we're practising unobtrusive JavaScript, the markup will start with headings separating the list items.

There's two approaches depending on your content. Either to use list elements or definition lists. Our example will use list elements.

<ul class="drawers">
  <li class="drawer">
    <h2 class="drawer-handle open">Downloads</h2>
      <ul>
        <!-- list items -->

And so on, with as many drawer elements as we want. Note that in this example, the 'open' class has only been applied to the first drawer.

Simple jQuery slide effect

In it's simplest form, the effect is this when the user clicks on the drawer handle:

  1. Hide all the drawer content elements
  2. Show the drawer content associated with the current drawer handle

In addition, when the page loads, we should hide all the drawer content, except for our starting point.

This is achieved with the following code:

$(document).ready(function () {
  // hide all ULs inside LI.drawer except the first one
  $('LI.drawer UL:not(:first)').hide(); 
  
  // apply the open class
  $('LI.drawer UL:first').addClass('open');
  
  $('H2.drawer-handle').click(function () {
    // hide the currently visible drawer contents
    $('LI.drawer UL:visible').hide();
    
    // remove the open class from the currently open drawer
    $('H2.open').removeClass('open');
    
    // show the associated drawer content to 'this' (this is the current H2 element)
    // since the drawer content is the next element after the clicked H2, we find
    // it and show it using this:
    $(this).next().show();
    
    // set a class indicating on the H2 that the drawer is open
    $(this).addClass('open');
  });
});

If you wanted to make better using of jQuery's chaining the code could be written as this:

$(function () { // same as $(document).ready(function () { })
  // assuming we have the open class set on the H2 when the HTML is delivered
  $('LI.drawer H2:not(.open)').next().hide();

  $('H2.drawer-handle').click(function () {
    // find the open drawer, remove the class, move to the UL following it and hide it
    $('H2.open').removeClass('open').next().hide();
    
    // add the open class to this H2, move to the next element (the UL) and show it
    $(this).addClass('open').next().show();
  });
});

If you want it to slide, we can easily swap .hide() for .slideUp() and .show() for .slideDown(), as I have done in the working example of the simple slide demo

If you look at the demo, for me, the annoying aspect is that the height changes depending on which drawer you've got open. In particular, if you have the first drawer open, and click on the second, the position of the third drawer handle moves up.

That's where the accordion plugin helps us.

jQuery accordion plugin

Using the same markup as the previous example, if we take Jörn Zaefferer's Accordion plugin we can match the effect on Apple's site.

Before we can use the plugin however, there are a few prerequisites: in particular, you must have the dimensions plugin. The best place to get the latest files is the plugin repository for Accordion. Download the zip file (using the link towards the foot of the page) and grab the following files:

  • jquery.accordion.js (or the packed versions)
  • lib/jquery.js (if you've not got the library already)
  • lib/jquery.dimensions.js

Again, using our existing markup, we can use the following code to get the plugin working straight away:

<script src="jquery.js" type="text/javascript"></script>  
<script src="jquery.dimensions.js" type="text/javascript"></script>  
<script src="jquery.accordion.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
$(function () {
  $('UL.drawers').accordion({
    // the drawer handle
    header: 'H2.drawer-handle',
    
    // our selected class
    selectedClass: 'open',
    
    // match the Apple slide out effect
    event: 'mouseover'
  });
});
-->
</script>

That's it! Simple and very easy to use so long as you have all the right files.

See the plugin version of the slide out effect

11 Trackbacks/Pingbacks

  1. Pingback: James Carr » Blog Archive » links for 2008-01-29 on January 29, 2008
  2. Pingback: ATOMICSHED » links for 2008-02-04 on February 4, 2008
  3. Pingback: 65 Excellent jQuery Resources (tutorials,cheat sheets,ebooks,demos,plugins…) | Speckyboy - Wordpress and Design on April 2, 2008
  4. Pingback: Brève 15: jquery, framework, HDR, AJAX, galerie, google on April 6, 2008
  5. Pingback: links for 2008-04-07 « toonz on April 7, 2008
  6. Pingback: 37 More Shocking jQuery Plugins on April 9, 2008
  7. Pingback: Elite By Design » Blog Archive » 19 Visual Effects That Entertain And Amuse on April 10, 2008
  8. Pingback: 37个更加出色的jQuery插件 | 帕兰映像 on April 10, 2008
  9. Pingback: e-octante » 37 plugins para jQuery on April 11, 2008
  10. Pingback: 37 plugins para jQuery « Think Free - Linux.Php.Java.ME.Movies on April 11, 2008
  11. Pingback: 37 More Shocking jQuery Plugins | SEO & Web Design on May 6, 2008

17 Comments

  1. Artzone
    January 21, 2008 at 09:55

    Hey great tutorial. Thanks for sharing this.

    I've been looking at the accordion plugin and wondered how I could make it remember which section was open when a link is clicked in that section. Let's say I have an accordion with 3 sections and I click a link in the second section. The new page loads and my accordion closes or it displays with the first section expanded. I'd really like it to stay open and display the links in the second section. Any thoughts on the best way of doing this?

    Cheers Art

  2. john cooper
    January 21, 2008 at 16:39

    Finally someone explaining how to use jQuery for simpletons like myself. Also showing the jQuery accordion can work without that annoying bounce effect! :D

  3. RickL
    January 24, 2008 at 22:56

    Has anyone else taken a look at the plugin version page in IE? There are problems...

  4. Remy
    January 25, 2008 at 01:23

    @RickL - I see what you're saying. There's an IE6 specific issue with the CSS.

    The actual plugin isn't broken, you can still roll over - it's just the colouring on the background looks strange. The styling was fairly complicated from the Apple web site, so it's no wonder it didn't drop in to IE6 perfectly - sorry!

  5. ajaxlearner
    February 1, 2008 at 00:45

    Hi, I tried to copy the source code on the demo page and try to run it as sample web application. It opens out all drawers and keeps them that way. The accordian effect is missing. Please help how i may have gone wrong.

  6. Remy
    February 19, 2008 at 01:13

    @ajaxlearner - without seeing your code, I'm having to guess, but if I were to guess, I would say that the ID is missing on the element that plays as the accordion - or doesn't match the ID used in the jQuery selector.

  7. Boz
    February 23, 2008 at 18:51

    Does not work with latest version of accordian plugin. Revision: $Id: jquery.accordion.js 2880 2007-08-24 21:44:37Z Works OK with the plugin used in the demo.

  8. Loren Helgeson
    February 25, 2008 at 20:59

    It's an excellent demo. Looks very promising. Only problem is that it doesn't work correctly in Safari, which is definitely ironic. The drawer tabs change, but the content disappears, and there is no slider effect.

  9. Remy
    February 26, 2008 at 00:05

    @Loren - I've just looked at my logs and can see you're on the very latest Safari (WebKit 523.12.2) - I've not upgraded to 10.5.2 yet, as such, the effect is fine on my machine (though I'll be upgrading this evening).

    I'll raise a bug with the jQuery UI guys if it's the plugin, or fix my code if it's on my side once I'm on the same version.

    Thanks for the heads up.

  10. Geoff
    March 3, 2008 at 13:49

    Hey guys have managed to get this script working perfectly in all browsers

    Had an issue where the content within the li would be overlapping the other sections when the animation ran, (ie 6+7) and also had an issue in ie6 where the background for the li wasn't showing.

    with a little bit of css tinerking im sure the guys above should be able to resolve their browser specific issues also.

    Nice work Remy

  11. Matt
    March 24, 2008 at 20:41

    @Geoff - Can you share any of the css you've done to get this working well across the various browsers? I've got most of it OK but still a few problems with ie5. I used the iepngfix.htc from www.twinhelix.com which helped.

    Cheers Matt

  12. Bernd Matzner
    March 27, 2008 at 15:11

    Hi,

    In the demo posted here, if I move my mouse to the third item, the second is opened and nothing happens.

    Last year, I published a draft for an accordion plugin that includes similar functionality, and uses Brian Cherne's hoverIntent plugin to detect if the user's mouse comes to a stop over an accordion section, so only the section the mouse is moved to opens up instead of every section the mouse crosses.

    See my site for samples: http://berndmatzner.de/jquery/hoveraccordion/

    Bernd

  13. Waiton
    April 11, 2008 at 11:16

    Hi there.

    Thanks so much for sharing this with us. With regard to the Accordian version, I've got most of it working and it works splendidly on IE6, but (believe it or not) on Firefox 2.0.0.13 and Safari 3.1, the li items in the preceding list overlaps with the heading of the list below them.

    Click on the gallery part of the site - it only happens the first time you load the gallery page though. And I've only got filler content on the first list so that's the only one that's breaking at the moment.

    http://www.digitaleasel.co.nz/gallery.php

    I've tried to simulate the problem by swapping in the code from the sample page and the problem is not repeated. I would use this code instead but I'm a novice and don't know how to change it so that you don't have to click the list header to open the list. You can see this at http://www.digitaleasel.co.nz/gallery2.php

    Any help would be great, but no worries if everyone's busy :) Hopefully you can see the code (I have the Web Developer Firefox add-on) - if not, I'll be happy to send it to someone.

    Cheers!

  14. Isko
    April 11, 2008 at 16:13

    Great tutorial! I'm new to jQuery but tutorials like this are excellent way to learn and start using more jQuery.

    I was wondering if there's a quick solution for a question I have concerning the simple slide demo. Is it possible to close the already opened drawer? Right now, if you click the open drawer, it closes and opens again. It would be more logical if it would just close the open drawer.

    I tried to play around with the code but didn't have much luck..

  15. Christopher Webb
    April 15, 2008 at 03:13

    I've noticed that the open drawers seem to open as wide as the tallest element within a drawer. For instance, drawer #1 has 2 lines of content and drawer #2 has 10 lines of content, but drawer #1 opens with 2 lines of content and 8 lines of empty space. Is there anyway to get them to open to their own specific sizes regardless of how big or small the others are?

  16. Chris
    April 16, 2008 at 22:54

    Excellent demo! I hope this trend of showing real world examples continues. I plan on using this in a template I'm building, and eventually make it into a plugin or module. Thanks a lot!

  17. Paul @ Web Design Ireland
    May 7, 2008 at 13:43

    @ Art - you can use a property on the jscript to keep it open at certain sections

    $(function () { $('ul.drawers').accordion({ header: 'H2.drawer-handle', selectedClass: 'open', event: 'mouseover', active: '.open' }); });

Leave a comment