Simple jQuery Accordion

jQuery

Make sure either to run on DOM ready or at the bottom of the page.

(function($) {
    
  var allPanels = $('.accordion > dd').hide();
    
  $('.accordion > dt > a').click(function() {
    allPanels.slideUp();
    $(this).parent().next().slideDown();
    return false;
  });

})(jQuery);

HTML

<dl class="accordion">

<dt><a href="">Panel 1</a></dt>
<dd>Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc.</dd>

<dt><a href="">Panel 2</a></dt>
<dd>Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.</dd>

<dt><a href="">Panel 3</a></dt>
<dd>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.</dd>

</dl>

SCSS

Sorry if you don't use SASS. Should be pretty easy to convert.

.accordion {
   margin: 50px;   
   dt, dd {
      padding: 10px;
      border: 1px solid black;
      border-bottom: 0; 
      &:last-of-type {
        border-bottom: 1px solid black; 
      }
      a {
        display: block;
        color: black;
        font-weight: bold;
      }
   }
  dd {
     border-top: 0; 
     font-size: 12px;
     &:last-of-type {
       border-top: 1px solid white;
       position: relative;
       top: -1px;
     }
  }
}

View Demo

Slightly more advanced, preventing closing of active panel:

View Demo

Comments

  1. User Avatar
    w1sh
    Permalink to comment#

    Thanks Chris. I was looking for a simple, lightweight alternative to all that jQueryUI jazz.

    • User Avatar
      Kevin
      Permalink to comment#

      Great share, however both demos function the same (clicking a new panel closes the previous). I believe once of the demos should function with the ability to open multiple panels at once.

    • User Avatar
      Avelino Tiu III
      Permalink to comment#

      Here’s a slightly modified version of this accordion: http://codepen.io/thirdtiu/pen/uDyxr

      Opened first panel, to indicate it’s an accordion..

      and added the ability to toggle open/close a tab.

  2. User Avatar
    Thomas
    Permalink to comment#

    This works well with just tags, but what if I have an image included with a tag? I added in some lines of code, but now when I click on a div, the images appear/disappear but no content ( tags) show up.

    Very odd……this is the code I used. Any help for someone learning Jquery would be appreciated greatly!

    $(document).ready(function() {

    $(‘#skills-services p:not(:first)’).hide();
    $(‘#skills-services img:not(:first)’).hide();

    $(‘#skills-services h3’).click(function(){

    $(‘#skills-services p’).slideUp();
    $(‘#skills-services img’).slideUp();
    $(this).next(“p”).slideToggle(“normal”)
    $(this).next(“img”).slideToggle(“normal”)
    return false;

    });
    });

  3. User Avatar
    Thomas
    Permalink to comment#

    I tried altering this code block to include images, but now only the images appear/disappear and the content ( tags) are nowhere to be seen.

    Very odd, but here is the code I used. Any help would be greatly appreciated to someone new to Jquery.

    $(document).ready(function() {
    	
    	$('#skills-services p:not(:first)').hide();
    	$('#skills-services img:not(:first)').hide();
    
    	$('#skills-services h3').click(function(){
    	
    		$('#skills-services p').slideUp();
    		$('#skills-services img').slideUp();
     	    $(this).next("p").slideToggle("normal")
    		$(this).next("img").slideToggle("normal")
            return false;
    
    	});
    });
    • User Avatar
      steve
      Permalink to comment#

      use divs like:

      .accordion {margin: 50px; position : relative; }

      .dt, .dd {
      padding: 10px;
      border: 1px solid black;
      border-bottom: 0;
      &:last-of-type {
      border-bottom: 1px solid black;} }

      .a {
      display: block;
      color: black;
      font-weight: bold; }

      .dd {
      border-top: 0;
      font-size: 12px;
      &:last-of-type {
      border-top: 1px solid white;
      position: relative;
      top: -1px;
      } }

      $(function(){
      (function($) {
      var allPanels = $(‘.dd’).hide();
      $(‘.a’).click(function() {
      allPanels.slideUp();
      $(this).parent().next().slideDown();
      return false;
      });
      })(jQuery);
      });

  4. User Avatar
    drizzy
    Permalink to comment#

    whoa never mind.. I didn’t close the tag

  5. User Avatar
    Devin Walker
    Permalink to comment#

    Is there a demo of this anywhere?

  6. User Avatar
    Drizzy
    Permalink to comment#

    is it possible for it to collapse more into sub heading as well?

    So basically if you had a heading:

    i.e.

    > Major Attractions ‘you click that it drops down to’
    > CN Tower ‘and when you click that it drops down
    > ‘a short description of the CN tower’

    is something like that possible ?

  7. User Avatar
    Rohan Merchant
    Permalink to comment#

    I made one to slide up the next one when you click the same one… I’m sure there’s a cleaner solution but I cant figure it out. If you do post back thanks.

    
    $.fn.equals = function(compareTo) { 
            if (!compareTo || !compareTo.length || this.length!=compareTo.length) 
    { 
                    return false; 
            } 
            for (var i=0; i<this.length; i++) { 
                    if (this[i]!==compareTo[i]) { 
                            return false; 
                    } 
            } 
            return true; 
    } 
    
    $(document).ready(function($) {
    		var whichOne = $('#accordion');
           $('#accordion dd').hide();
           $('#accordion dt a').click(function(){
           		if(whichOne.equals($(this))){
           			$('#accordion dd').slideUp();
           			$(this).parent().next().next().next().slideDown();
             		whichOne = $(this).parent().next().next().next();
                }else{
    	            $('#accordion dd').slideUp();
    	            $(this).parent().next().slideDown();
    	            whichOne = $(this);
    	            
                }
    			return false;
           });
    });
  8. User Avatar
    Patrick
    Permalink to comment#

    How can I use this with WordPress’ dynamic navigation?

  9. User Avatar
    Beschi

    Thanks.
    This gives me some more ideas on accordion.

  10. User Avatar
    Caleb Kester
    Permalink to comment#

    Awesome! just what I was looking for!

  11. User Avatar
    Kai
    Permalink to comment#

    Hi, Thanks for the tutorial, just what iw as looking for.

    Just 1 quick question, how would i make the tabs collapsible, so that all can be closed?

    i have tried adding in ‘collapsible: true’ but to no avail.

    Thanks

    • User Avatar
      Bert de Vries
      Permalink to comment#

      I did this:

      $(document).ready(function($) {
             $('#accordion dd').hide();
             $('#accordion dt a').click(function(){
                if ($(this).hasClass('selected')) {
                     $(this).removeClass('selected');
                     $(this).parent().next().slideUp();
                } else {
                     $('#accordion dt a').removeClass('selected');
                     $(this).addClass('selected');
                     $('#accordion dd').slideUp();
                     $(this).parent().next().slideDown();
                }
                return false;
             });
      });

      Works for me…

      Gr. Bert

  12. User Avatar
    __fabrice
    Permalink to comment#

    Hi,
    To avoid the “jump” bug, just add : position : relative; on a parent div.

    Fabrice

    • User Avatar
      Farid Hadi
      Permalink to comment#

      position : relative; on the definition list itself would also do the trick and you that way you don’t need the extra div : )

  13. User Avatar
    dan
    Permalink to comment#

    i came up with an even simpler solution:
    you don’t have to override the accordion click function because by calling accordion(“activate”, false) the all parts are closed (and hiding helps that this is not seen by the user). i also set collapsible to true… don’t know if thats necessary.

    $(document).ready(function($) {
    	// hide all content if the hash is null
    	if (window.location.hash == "") {
    		$("#accordion .content").hide();
    		$("#accordion").accordion("activate" , false);
    	}
    });
  14. User Avatar
    WebVeins.in
    Permalink to comment#

    It solved my problem.
    Thanks a lot.
    Keep rocking…

  15. User Avatar
    Red
    Permalink to comment#

    Simple and effective!

  16. User Avatar
    Ricardo Zea
    Permalink to comment#

    The best way to avoid page jumping is to not use dummy links (a href=”#” or a href=””) at all. a href’s have a lot of SEO weight so you may want to use them to actually link to other pages/sites, not to trigger behaviors.

    To trigger behaviors you can use any other HTML link, yes, it will work, all you’d have to do is add “cursor:pointer;” to your CSS file and that’s it. And yes, this works in IE6 too.

    So in Chris’s example above just replace:

    <a href=””></a>

    with:

    <span></span>

    • User Avatar
      Tim
      Permalink to comment#

      Hey Ricardo,
      good tip. I’m by *no* means a developer and am just learning this stuff.

      How would you use the span?

      <dt><span>\"How do you choose the coffee?\".</span></dt>

      or

      <dt><span class="spanclass">\"How do you choose the coffee?\".</span></dt>

      And then swap

      $('.accordion > dt > a').click(function() {

      for

      $('.accordion > dt > span').click(function() {

      This is being used on maydaycoffee.com.au for FAQs.

  17. User Avatar
    Ruana
    Permalink to comment#

    Hi,

    unfortunately the “jump” remains, at least in IE7, not matter whether one applies a position: relative; on a parent div or replaces the dummy links with real links or a spans – with which the indication that the lines are links is missing is not clear to the user. The headlines must unmistakable scream: Click me, I’m a link! to the users).

    If anyone could come up with a solution to get rid of that nasty jump (in IE7 too) and post it here I’d be very grateful.

    • User Avatar
      adam

      The return false should prevent the jump // but you can also the following: adding an event to the click function and then immediately preventing the default behavior /

      function accordian(){

      $(‘.accordian dd’).hide();
      $(‘.accordian dt a’).click(function(event){ // <– add the event

      event.preventDefault(); // <— prevent the jump
      $('.accordian dt a').click(function(){

      $('.accordian dd').slideUp();
      $(this).parent().next().slideDown();

      });

      });

      }

  18. User Avatar
    Paul
    Permalink to comment#

    Regarding the jump……

    If the container which is being animated ( the dd) has margin or padding this seems to greatly increase the jump.

    If you put your content inside a and put the padding on that instead of the , this seems to greatly reduce the jump.

    Text

  19. User Avatar
    Paul
    Permalink to comment#

    Ooops … hope this works :-/

    &ltdd&rt&ltp&rtTEXT&lt/p&rt&lt/dd&rt

    • User Avatar
      Paul
      Permalink to comment#

      No .. I’m obviously stupid :-/ Antway, just put the P inside the DD :-)

  20. User Avatar
    Richard
    Permalink to comment#

    I’ve been searching for a simple accordion script and this might just be the one. Others I’ve found are very convoluted but this one is nice and lightweight, thanks.

  21. User Avatar
    Livepage
    Permalink to comment#
  22. User Avatar
    Daryl
    Permalink to comment#

    Hey guys, this is great – on every browser except IE7.
    I have tried every hack out there to get it to work but it’s just not working. Any hints?

    • User Avatar
      Daryl
      Permalink to comment#

      I apologise, after hours of lost sleep I tried a new attack. It turns out the IE7 I had installed on my mac (using Winebottler) wasn’t loading ANY javascript and couldn’t be modified.
      The script still works beautifully as intended.

  23. User Avatar
    Nicole

    great article I using the following code

    $(document).ready(function() { 
      /*
      SIMPLE ACCORDIAN STYLE MENU FUNCTION
      */ 
      $('div.accordionButton').mouseover {
              $('div.accordionContent > .acitem', this).show();
              $('div.accordionContent > .acitem', this).prev().addClass('active');
        $('div.accordionContent').slideUp('slow');  
        $(this).next().slideDown('slow');
    
      });
    
      /*
      CLOSES ALL DIVS ON PAGE LOAD
      */ 
      $("div.accordionContent").hide();
    
    });
    

    now all the menu will closed at once, i want one menu should be open and remaining closed, how it can be achieved? or slow menu closing will also do.

  24. User Avatar
    Biju Subhash

    thank you for sharing…
    here an another link for another jquery accordion:
    http://www.bijusubhash.com/blog/create-a-simple-accordion-with-jquery-and-css

  25. User Avatar
    png
    Permalink to comment#

    would like to know if you are still answering any of the comments in this thread, simple jquery accordian
    thanks

  26. User Avatar
    Xirc
    Permalink to comment#

    Great, simple, thanks!
    Could you help to support cookies and remember open &ltdt>?

  27. User Avatar
    Stephen McCann
    Permalink to comment#

    Hi there, is it possible to implement this menu with more than one dd tag? I understand it goes against definition lists… can I use li tags instead? Sorry I’m pretty new to jQuery, any help would be much appreciated. The list I’m trying to implement would have the structure:

    Projects 
      - project1
    - project2 
    etc
    

    Thanks guys!

    • User Avatar
      jamie paterson
      Permalink to comment#

      Change them to DIV’s and put the lists inside mate. :-)

  28. User Avatar
    john
    Permalink to comment#

    thank. gracias desde colombia. me sirve muchisimo.

  29. User Avatar
    Sam Pethers
    Permalink to comment#

    Thanks so much. Really clear article.

  30. User Avatar
    Ion Ceban
    Permalink to comment#

    Thanks for the tutorial, it really help me a lot.

  31. User Avatar
    Josh
    Permalink to comment#

    Im having a weird bug with this code as it is posted originally. If you click one of the menu items to expand it does expand but if you click the same menu item to close it, it bounces closed then open again.

    Does anyone know how to turn this bounce off?

  32. User Avatar
    PC Support Guy
    Permalink to comment#

    damn, i just spent an hour getting this to work but cant get rid of that annoying jump it does. read all these comments and still get the jump….ok back to the drawing board. there has to be something simpler out there.

  33. User Avatar
    Ajay
    Permalink to comment#

    Great script..

    Is there a way to get the first item in the accordion to be open on page load rather than hiding all?

  34. User Avatar
    Bacca
    Permalink to comment#

    I’m having the same problem as Josh (01/26/2012)

    Does anyone know how to turn this bounce off?

    It would be nice to have the option to close the menu item you have just opened

    • User Avatar
      Ravi G
      Permalink to comment#

      Remove # from the link tag and use ‘ href=”js:;” ‘ instead.

  35. User Avatar
    Mahmoud

    Hello !
    Thanks for posting this amazing tut, its really simple, I was just need to know, is that possible to make this accordion work dynamic, for example if am working on eCommerce website and i have more than one item is that possible while am scrolling the accordion open panel for the item name something like giving order to accordion panel. Any help.
    Sorry for my English. Thanks

  36. User Avatar
    Davey

    @Josh and @Bacca – You can fix the bounce open and closed with this:

    (function($) {
    
      var allPanels = $(‘.accordion > dd’).hide();
    
      $(‘.accordion > dt > a’).click(function() {
        allPanels.slideUp();
        if($(this).parent().next().is(‘:hidden’)) {
          $(this).parent().next().slideDown();
        }
        return false;
      });
    
    })(jQuery);​
    
    • User Avatar
      Greg
      Permalink to comment#

      Almost similar with your’s solution, this works for me and i submit it as an alternative solution:

      var allPanels = $('.accordion > dd').hide();
      
      $('.accordion > dt > a').click(function()
      {
          allPanels.slideUp();
      
          if($(this).parent().next().css('display')=='none')
          {
              $(this).parent().next().slideDown();
          }
          return false;
      });
      
    • User Avatar
      Josema
      Permalink to comment#

      Thanks Davey! this solve when you click on an open tap

    • User Avatar
      Anja
      Permalink to comment#

      Wow Davey, you solved my problem of being able to close each item with just one simple line of code! Genius!

  37. User Avatar
    Bacca

    Hi Davey,

    Thanks for taking time to look at this, unfortunately I tried this solution and it was unsuccessful .

    When the page loads all the dds are open and clicking on the links in the dts does nothing?

    Any ideas??

  38. User Avatar
    Davey

    Hey Bacca,

    If you copied and pasted from my previous comment, the formatting creates an improper ” ‘ ” character. I forked the previous demo on jsfiddle here:

    http://jsfiddle.net/8MXAu/

    Try that. I tested it on jsfiddle and it was fine. This would also assume that you are using the same HTML and CSS as the example.

    • User Avatar
      Chris
      Permalink to comment#

      Thanks Davey, that worked great and I am using different css than Chris. I changed the scss to old format and changed from there to fit my theme. Thnx again!

    • User Avatar
      JYoho
      Permalink to comment#

      Thanks Davey! That worked great and solved the bounce issue :)

    • User Avatar
      Pierre Schilling
      Permalink to comment#

      Thank you for this code!

  39. User Avatar
    Jon

    Davey-

    I just came across this demo. The original works fine except the “jump” your fix breaks completely. Any idea why that may be the case?

  40. User Avatar
    Davey

    Hey Jon,

    Check out the jsfiddle link here:
    http://jsfiddle.net/8MXAu/

    If you copied the fix from my previous comment, it does break because of an invalid ‘ character. Is that how you tested it?

    • User Avatar
      Bacca

      Thanks Davey,

      I had noticed the invalid character after I copied it, thought I had changed them all but must have missed one.

      Anyway keyed in code from scratch (which i should have done in the first place) and it works perfectly, many thanks.

    • User Avatar
      faris
      Permalink to comment#

      thanks alot mate. your fix works. cheers

  41. User Avatar
    Zachattack
    Permalink to comment#

    This snippet helped me immensely. Thank you for sharing.

  42. User Avatar
    max
    Permalink to comment#

    Not a jquery expert,

    need to have several accordions in 6 columns any ideas how to do this? my js fiddle http://jsfiddle.net/FL7q3/

  43. User Avatar
    Tim Smith
    Permalink to comment#

    This i great!
    How do I only show one panel at a time?

  44. User Avatar
    Tiffany Israel
    Permalink to comment#

    Any idea how to add a window.scrollTo? I’m not super proficient in Javascript/jQuery expert so I’m not sure where to put it.

  45. User Avatar
    JHawes
    Permalink to comment#

    I tried this to allow for accordion tabs (dt) to be collapsible once opened:

    $(document).ready(function($) {
           $('#accordion dd').hide();
           $('#accordion dt a').click(function(){
              if ($(this).hasClass('selected')) {
                   $(this).removeClass('selected');
                   $(this).parent().next().slideUp();
              } else {
                   $('#accordion dt a').removeClass('selected');
                   $(this).addClass('selected');
                   $('#accordion dd').slideUp();
                   $(this).parent().next().slideDown();
              }
              return false;
           });
    });
  46. User Avatar
    Chuck Ezuma
    Permalink to comment#

    This is one of the better accordion demonstrations. Nice and clean.

  47. User Avatar
    MP
    Permalink to comment#

    Nice tutorial…

    Has anyone incorporated a [+] and [-] into this accordion, either by way of Javascript or images?

    That would be really really cool if someone did…!

    • User Avatar
      Krish
      Permalink to comment#

      Hi MP,

      I did my accordion with Plus and Minus signs, but there is one small bug in it. When I click the icons are jumping. Is there any solution for the icons jumping?

      Krish

  48. User Avatar
    Tim
    Permalink to comment#

    I could not get this working. Mainly as I am a n00b and didn’t know about swapping $ for jquery.
    Also a bit of jquery lightbox wizardry I am using caused a conflict.

    Here’s how it was fixed.

    I got my mate whom I use for dev (and who kicks butt) to fix this and we have this working on maydaycoffee.com.au.

    The jquery used is:

    <script src='http://code.jquery.com/jquery-latest.js'></script>
    								<script>
    								jQuery(document).ready(function()
    								{
    									var allPanels = jQuery('.accordion > dd').hide();
    									
    								    jQuery('.accordion > dt > a').click(function()
    								    {
    								        allPanels.slideUp();
    								        
    								        if(jQuery(this).parent().next().is(':hidden'))
    								        {
    								            jQuery(this).parent().next().slideDown();
    								        }
    								        return false;
    								    });
    								});
    </script>

    CSS is below. I converted from SCSS. Like I said, I am not a dev/designer so my syntax and probably semanticism SUCKS.

    .accordion dt, .accordion dd {
    		padding: 5px;
          border: 1px solid #815611;
          border-bottom: 0; 
          font-family: inherit;
    	  font-size: 0.9em;
    
          &:last-of-type {
            border-bottom: 1px solid black; 
    		}
    }
    
    .accordion dt a, .accordion dd a
      {
            display: block;
            color: inherit;
            text-decoration: none;
            font-weight: bold;
          }
    
    .accordion dd {
    
         border-top: 0; 
         font-size: inherit;
         &:last-of-type {
           border-top: 1px solid #815611;
           position: relative;
           top: -1px;
    	}
    }
    
    .accordion dt{
    color: #A90329;
      margin-top: 1em;
    }
    • User Avatar
      quiet0ne
      Permalink to comment#

      Awesome, this worked perfectly. Thank you for sharing that solution!

  49. User Avatar
    Vivek Moyal
    Permalink to comment#

    Awesome !!! cool code for making a very simple jquery accordion.

  50. User Avatar
    Oimy

    god bless you, Chris!

  51. User Avatar
    Jeppe
    Permalink to comment#

    Hi, just a quick question. I’m trying to change the selectors to ul and li instead of dd dl and so on. But it wont seem to work. Any ideas?

    Thanks in advance
    /Jeppe

  52. User Avatar
    Jeppe
    Permalink to comment#

    Hello agian,

    forget about my previous question. I solved it by actually closing all elements :)

    How ever I have another qestion. If one wants for the clicked panel to scroll to top och into view. How would I do that out from your code?

    Thanks!
    /Jeppe

  53. User Avatar
    Annabelle du Blogovoyage
    Permalink to comment#

    Hi,

    For those who are looking for a French accordion tutorial, here is a great one : http://netmacom.fr/blog/webdesign/creer-un-menu-accordeon-avec-jquery.html

  54. User Avatar
    Brian
    Permalink to comment#

    To get the first one to show (previous solution someone posted didn’t work).

    I did:

    var allPanels = $('.accordion > dd').hide().first().show();
    
  55. User Avatar
    Brian
    Permalink to comment#

    Errr ignore the previous post, it breaks it.

    Just add this line below the var allPanels line:

    $('.accordion > dd').first().show();
    
  56. User Avatar
    Ramesh Chowdarapally
    Permalink to comment#

    It can be used as fundamental, but not as advanced.

  57. User Avatar
    Pierre
    Permalink to comment#

    My accordion version at his simplest. Style it as you wish. h3 can be replace by anything…

    JQuery (Javascript):
    $(document).ready(function() {
    $(‘[id^=aContent]’).hide();
    $(‘[id^=aContent]’).prev().click(function() {
    $(‘[id^=aContent]’).hide(300);
    if ($(this).next().is(“:visible”))
    $(this).next().hide(300);
    else
    $(this).next().show(300);
    });
    });

    CSS:
    .aHeaders {/* Put the style for your accordeon headers here… */}
    .aContents {/* Put the style for your accordeon contents here… */}

    HTML:
    <h3 class=”aHeaders”><a href=”#aContent1″>Header 1</a></h3>
    <div class=”aContents” id=”aContent1″>
    Content1
    </div>
    <h3 class=”aHeaders”><a href=”#aContent2″>Header 2</a></h3>
    <div class=”aContents” id=”aContent2″>
    Content2
    </div>
    <h3 class=”aHeaders”><a href=”#aContent3″>Header 3</a></h3>
    <div class=”aContents” id=”aContent3″>
    Content3
    </div>

    Cheers!
    -Pierre-

  58. User Avatar
    onykage
    Permalink to comment#

    I edited Pierre’s snippit to allow the first element to be displayed on load.

    $(‘[id^=aContent]’).hide();
    $(‘[id^=aContent]’).first().show();
    $(‘[id^=aContent]’).prev().click(function() {
    $(‘[id^=aContent]’).hide(500);
    if ($(this).next().is(“:visible”)){
    $(this).next().hide(500);
    } else {
    $(this).next().show(500);
    }
    });

    Cheers

  59. User Avatar
    Ben
    Permalink to comment#

    @Kevin: if you want to open multiple dd elements at once, do this:

    $('.accordion > dt > a').click(function(e) {
      e.preventDefault();
      e.stopPropagation();
        $(this).parent().next().slideToggle();
        return false;
    });
    
  60. User Avatar
    Simon Foust
    Permalink to comment#

    Brilliant — thanks Chris.

    I added an active class for the dt. Not a strong writer of jQuery so for anyone who might improve this, thank you in advance:

        (function($) {
          var allTriggers = $('.accordion > dt');
          var allPanels = $('.accordion > dd').hide();
          $('.accordion > dt').first().addClass('active');
          $('.accordion > dd').first().show();
          $('.accordion > dt > span.toggle').click(function() {
              $this = $(this);
              $target =  $this.parent().next();
              if(!$target.hasClass('active')){
                 allPanels.removeClass('active').slideUp();
                 $target.addClass('active').slideDown();
              }
              $trigger =  $this.parent();
              if(!$trigger.hasClass('active')){
                 allTriggers.removeClass('active');
                 $trigger.addClass('active');
              }
            return false;
          });
        })(jQuery);
    
  61. User Avatar
    AK
    Permalink to comment#

    You can further simplify it by using JQuery “.accordion()” function. Since you do not have to do much except designing it using CSS. All you need is couple of elements inside a container and let the JQuery do the rest.
    Its that simple.

  62. User Avatar
    Michelle
    Permalink to comment#

    Your tutorial has converted me into using SASS. Thank you!

  63. User Avatar
    Michelle
    Permalink to comment#

    I got it working! Although there is one thing that isn’t working properly and I can’t seem to be able to fix it. When I click on a panel, the description opens but as it opens, the width is smaller. When it has finished loading, it bumps to its full-length. How do I fix this? http://michellecantin.ca/test/features/accordions/

  64. User Avatar
    Cynthia
    Permalink to comment#

    Hi how do I build an accordion within an accordion? please help! thanks!

  65. User Avatar
    Christopher
    Permalink to comment#

    Sweet, worked first time, I even managed to convert the css back to ‘normal’ on the first try. I am using this accordion for an FAQ section. For those who aren’t familiar with sass here is the css I used, it’s very much the same, but no-doubt someone has been cought out by that ‘&’:

        .accordion {
        margin: 30px;
        position: relative;
           }
            .accordion dt, .accordion dd{
                padding: 10px;
                border: 1px solid black;
                border-bottom: 0;
            }
            .accordion dt:last-of-type, .accordion dd:last-of-type {
                border-bottom: 1px solid black;
            }
        dt a, dd a {
            display: block;
            color: black;
            font-weight: bold;
        }
        dd {
            border-top: 0;
            font-size: 16px;
        }
            dd:last-of-type {
                border-top: 1px solid white;
                position: relative;
                top: -1px;
            }
    
  66. User Avatar
    Michele
    Permalink to comment#

    Hi there,
    Can someone explain this line in the code for me?
    $(this).parent().next().slideDown();
    If (this) is referring to $(‘.accordion > dt > a’), then wouldn’t that line refer to the title of each panel and not the paragraph of text in the panel that needs to be displayed?

    I’m also unclear as to why this: (function($) { })(jQuery); needs to wrap the entire function in order to work.

    Thanks!

    • User Avatar
      christopher
      Permalink to comment#

      ‘this’ always refers to the current object, to find out what it is use
      console.log( “what is this? ” + $(this).parent() );
      right before or right after the line you quoted, and then read the output from the console. I think in the accordion it is the parent of the clicked object > next sibling of that parent object. So the start of the next element that will ‘open’.

      Your second question is answered here
      stack overflow, answer by Vivin Paliath -scroll down for the answer

  67. User Avatar
    erez
    Permalink to comment#

    to make it unclickable when open

    $j(‘.accordion > dt > a’).click(function() {
    allPanels.slideUp();
    if($j(this).parent().next().css(‘display’) != ‘block’){
    $j(this).parent().next().slideDown();
    return false;
    }
    });

  68. User Avatar
    Josiah Nusbaum
    Permalink to comment#

    Does anyone know how to make it so that you can close the “open drawer”? I’m using this in a website for a class, and my teacher is taking away points because the “open drawer” won’t close.
    Thanks in advance for your help!

    • User Avatar
      christopher
      Permalink to comment#

      If you mean that all of the accordion sections should be closed on start, you can do something like:
      var allPanels = $( '.accordion &gt; dd' ).hide();

      and that should hide all of the contents of anything with an .accordion class. To show only the first on load add after that line:
      $('.accordion &gt; dd').first().show();

  69. User Avatar
    Cameron
    Permalink to comment#

    How would you add the plus minus sign to it?

    Thanks!

    • User Avatar
      christopher
      Permalink to comment#

      Add a class to the element you want to add the +- icons to then use something akin to;
      css:
      .notselected{
      background: url(‘plusIcon.png) no-repeat;
      background-position{ 98% 50%; /* horiz, vert */
      }

      In the main js/jquery function:
      var allHeaders = $(‘h1.accHeader’).addClass(‘notselected’);
      $(allHeaders).first().removeClass(‘notselected’);

      Where h1.accHeader (in my code) is a clickable header (dt.a in the example)
      And then in your onclick function you will need to reverse it:

      allHeaders.addClass(‘notselected’);
      $(this).removeClass(‘notselected’);

  70. User Avatar
    Sam

    Great snippet, thank you. Has anyone tested this for mobile? Works great on the iPhone 5. I ask because this would be an excellent solution for mobile menus.

    Sam

  71. User Avatar
    Alan Sutherland

    Thanks for this dude

  72. User Avatar
    ashish
    Permalink to comment#

    It has some issues with pagination……it doesn’t work when you go to the next page using pagination.

  73. User Avatar
    Michael
    Permalink to comment#

    I know this post is pretty old now, but I would sitll like to say thanks a lot for this write up, the comments are a gold mine as well.

  74. User Avatar
    Andrey
    Permalink to comment#

    With promises:

     jQuery(document).ready(function($) {
                var whichOne = jQuery('dl.faq');
                jQuery('dl.faq dd').hide();
    
                jQuery('dl.faq dt').click(function(){
                    var selected = jQuery(this).next();
                    jQuery('dl.faq dd').each(function() {
                        if(this != selected)
                            jQuery(this).slideUp();
                    }).promise().done(function() {
                            jQuery(selected).slideDown();
                        });
                });
            });
    
  75. User Avatar
    John Sheahan
    Permalink to comment#

    Thanks Chris, this is fantastically lightweight & easily to implement!

  76. User Avatar
    David Condrey
    Permalink to comment#

    Here’s a good full-page horizontal accordion I just finished putting together -> http://codepen.io/dcdev/full/azvGwm/

  77. User Avatar
    Peter Sorensen
    Permalink to comment#

    Thanks Chris! Love the simplicity. I’ve adapted this example to include a no-js fallback, which also hides elements via CSS to avoid flash of un-styled content caused by hiding elements via jQuery.

    See the Pen zxqExq by Peter Sorensen (@ptrsrsn) on CodePen.

  78. User Avatar
    Arif Samad
    Permalink to comment#

    i want to add arrows in the accordion, when website load all panel shows right arrow and when i click on one panel it show the down arrow

    how can i do that?

  79. User Avatar
    Pavol Hudran
    Permalink to comment#

    I have better script:

    $( document ).ready(function() {
         
      var allHeaders = $('.accordion dt');
      var allPanels = $('.accordion dd');
      allPanels.hide();
          
      $('.accordion dt').click(function() {
        allHeaders.not($(this)).removeClass('open');
        allPanels.slideUp();
        if (!$(this).hasClass('open')) {      
          $(this).next('dd').slideDown();
          $(this).addClass('open');
        } else {
          $(this).removeClass('open');
        }
        return false;
      });
    
    });
    
  80. User Avatar
    Tony Shaw

    To nest multiple accordion instances, one inside the other, replace the call to: allPanels.slideUp(); (in the original code) with the line below:

        // allPanels.slideUp();
        $(this).closest("dl").find("dd").slideUp();
    
  81. User Avatar
    Jonathan
    Permalink to comment#

    Nice and simple, but I like this functionallity a bit better:

    (function($) {

    var allPanels = $(‘.accordion > dd’).hide();

    $(‘.accordion > dt > a’).click(function() {
    allPanels.not($(this).parent().next()).slideUp();
    $(this).parent().next().slideToggle();
    return false;
    });

    })(jQuery);

  82. User Avatar
    Jason
    Permalink to comment#

    One issue…. when I click on an anchored link to the related tab on the accordion… the screen drops to the bottom of the screen in chrome… no matter where I place my

  83. User Avatar
    Pierre Schilling
    Permalink to comment#

    Hi, it is really the better code I’ve found so far. I’m currently looking to a complement to have the panel go back top instead of staying at the bottom when I click on the next.
    If someone have an idea, I would be very very grateful!

  84. User Avatar
    irfan mark
    Permalink to comment#

    Hello !
    Thanks for posting this amazing tut, its really simple, I was just need to know, is that possible to make this accordion work dynamic,

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

Submit a Comment

icon-closeicon-emailicon-linkicon-menuicon-searchicon-tag