Tutorials

Latest Word » Tutorials » Simple Accordion w/ CSS and jQuery
thumb

Simple Accordion w/ CSS and jQuery

Tags: ,

Please note: This tutorial requires basic knowledge of CSS and jQuery. For best results, please be sure to learn the proper foundations before attempting to take this tutorial. Learn one step at a time :-)

When designed and implemented with usability in mind, the accordion can be incredibly useful when organizing a good chunk of content. Since a lot of people found my toggle tutorial useful, I would like to go over how I approached building an accordion from scratch.

jQuery Accordion Tutorial

Foundation – HTML

Our markup is pretty simple, an <h2> and <div class="acc_container"> following right after. The <h2> is the heading of our accordion item. We will be using this as our trigger w/ jQuery. The <div class="acc_container"> is what will be sliding up and down to show its content.

<h2 class="acc_trigger"><a href="#">Web Design &amp; Development</a></h2>
<div class="acc_container">
    <div class="block">
	<!--Content Goes Here-->
    </div>
</div>

Styling – CSS

There are two important parts to pay special attention to in the styles.

  1. Fixed width on the .acc_container (Cannot be in % or em). This prevents an unusual jQuery bug where it jumps/skips when the accordion is sliding down (right when it reaches the bottom). I’ve researched this and some suggested specifying a height with jQuery, but I found my solution to be much more simple and effective.
  2. Add padding to the nested div in the .acc_container. This prevents another bug where the padding is animated when the accordion is in opening/closing.
h2.acc_trigger {
	padding: 0;	margin: 0 0 5px 0;
	background: url(h2_trigger_a.gif) no-repeat;
	height: 46px;	line-height: 46px;
	width: 500px;
	font-size: 2em;
	font-weight: normal;
	float: left;
}
h2.acc_trigger a {
	color: #fff;
	text-decoration: none;
	display: block;
	padding: 0 0 0 50px;
}
h2.acc_trigger a:hover {
	color: #ccc;
}
h2.active {background-position: left bottom;}
.acc_container {
	margin: 0 0 5px; padding: 0;
	overflow: hidden;
	font-size: 1.2em;
	width: 500px;
	clear: both;
	background: #f0f0f0;
	border: 1px solid #d6d6d6;
	-webkit-border-bottom-right-radius: 5px;
	-webkit-border-bottom-left-radius: 5px;
	-moz-border-radius-bottomright: 5px;
	-moz-border-radius-bottomleft: 5px;
	border-bottom-right-radius: 5px;
	border-bottom-left-radius: 5px;
}
.acc_container .block {
	padding: 20px;
}

Step 3. Setting up jQuery

For those who are not familiar with jQuery, do check out their site first and get an overview of how it works. I’ve shared a few tricks that I have picked up along the way, you can check those out as well.

Initial Step – Call the jQuery file

You can choose to download the file from the jQuery site, or you can use this one hosted on Google.

<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>

Directly after the line where you called your jQuery, start a new <script> tag and start your code by using the $(document).ready event. This allows your jQuery code to run the instant the DOM is ready to be manipulated. The code you will be writing in the next few steps will all take place within.

$(document).ready(function() {
	//Code goes here
});

Bringing it to Life – jQuery

The following script contains comments explaining which jQuery actions are being performed.

//Set default open/close settings
$('.acc_container').hide(); //Hide/close all containers
$('.acc_trigger:first').addClass('active').next().show(); //Add "active" class to first trigger, then show/open the immediate next container

//On Click
$('.acc_trigger').click(function(){
	if( $(this).next().is(':hidden') ) { //If immediate next container is closed...
		$('.acc_trigger').removeClass('active').next().slideUp(); //Remove all "active" state and slide up the immediate next container
		$(this).toggleClass('active').next().slideDown(); //Add "active" state to clicked trigger and slide down the immediate next container
	}
	return false; //Prevent the browser jump to the link anchor
});

The Logic – What’s Happening Here?

  1. First set the default settings: Open first accordion and add active state.
  2. On click: Find out if the clicked accordion item is opened or closed.
  3. If clicked item is “hidden” (closed) then…
  4. On all accordion items – Remove all “active” classes and slide up (close) all immediate next .acc_container.
  5. On clicked trigger $(this) – Add “active” state and slide down the immediate next .acc_container.

Next()

Related Articles Elsewhere

Related Posts

Author Bio

My name is Soh Tanaka and I am a Los Angeles based designer/front-end developer specializing in CSS driven web design with an emphasis on usability and search engine optimization. I also run a CSS Gallery which is updated daily with the best CSS websites from around the world. Come check it out!

You can learn more about me or Twitter  Follow me on twitter for more updates and resources!

Did You Enjoy This Post?

subscribe  Subscribe via RSS or by email to get all upcoming tutorials and articles delivered straight to you.

+ Add Comment83 Peeps Have Spoken Their Minds...

  1. zac

    Your site is da bomb and your side scroll bar… brilliant! Thanks for sharing your smooth accordion, one of the best I have seen.

  2. Josh

    Once again, another great peice of jquery to use in any projects. Visiting often and always waiting for the next post.

  3. Bheku

    As usual, you don’t dissappoint. Thanks for a great article.

  4. Greg Babula

    Awesome, thanks bro!

  5. Deef

    Awesome post, as usual.
    And nice job on the site redesign!

  6. Nepal kathmandu

    Great post. I have been looking something like this for a while. Thank you for uploading such great quality tutorials.

  7. Steve

    Awesome. Easy to follow! Will be using this on my site. =) Thank you

  8. Rachel

    Nice solid tutorial… seems relatively simple but highly effective…thanks..

  9. Michael Østergaard

    I’m curious, which plugin (if any) did you use for code examples?

    Btw, great and useful tutorial. Use it already :D

  10. Soh

    @Michael, I actually didn’t use any plugins for this. Just your typical pre tags, and some jQuery to animate it to expand :-)

  11. Amos

    This is what i like the most, the simplicity but the power of a few lines of code, not everyone can achieve this of course.

    Nice desing.

  12. Jesse

    Love it. Thank you.

  13. Smashing Web Development

    Simple, clean and effective! This is a cool tut thanks.

  14. Eko Priyanto

    Nice Deigns :) Thanks

  15. Alex Flueras

    Smooth sliding, great looking accordion. Thanks so much for this tutorial.

  16. Jason Day

    Great simple toggle.

    Is there any way to force only one toggle open at a time?

  17. Hank

    Awesome, love it! Also, I noticed something is whacky with your Simple Tabs tutorial in Google Chrome, works great in IE and FF, but for some reason the first tab’s content isn’t appearing when the page loads, you have to click on a tab to get the content to load. Once loaded you can move from tab to tab as expected, but a refresh clears the tab content and again your just looking at the tabs themselves! I tried both dev and release versions of Chrome. Any ideas? Thanks.

  18. Soh

    @Hank Thanks! That is strange, my chrome seems to be showing the first tab and it’s content fine.

  19. Hank

    @SOH hmm… This is frustrating! I’m using 5.0.396.0 So weird, I’ve tried on both my work and home PCs. Using dev tools I’ve narrowed down the problem to Chrome not styling the tab_content for with the appropriate “display: block;” CSS. Instead it stays “display: none;” In IE and Firefox it gets the appropriate inline styling. I’ve linked some screen shots: http://picasaweb.google.com/lh/photo/ie66Pd9qJvoe5jfIc2PEZQ?feat=directlink
    http://picasaweb.google.com/lh/photo/OOHoXFKRZ6mt7CFWU0jMHQ?feat=directlink Maybe I’m just crazy, but this issue has been driving me nuts! Thanks again, your tutorials are awesome!

  20. SOR

    good code, thank you for you share

  21. Michael Østergaard

    @SOH, thanQ for the quick answer. Like the idea of the code examples expanding.

  22. Marianne Ingrid Moner

    Hi,

    I love this! I am having a problem however (IE of course!) This looks great in other browsers, but in IE, the accordion behaves as though it’s in a wrapper and sits center stage, moving as though I have a wrapper on the body. I have the entire accordion housed in a div which is position:absolute. Is there a workaround for IE? Or, do you have any suggestions? The site is not live, but on my server so I can test it.

    MIM

  23. Soh

    @MARIANNE Does this happen on the demo? I’ve checked in all versions of IE and it seems to be working correctly for me.

  24. Marianne Ingrid Moner

    Hi,

    No, it doesn’t happen on the demo. In the demo, the accordion is in the center of the page. On my page I have it on the left – but in IE it appears in the center.

    In the event you didn’t see my URL, the site can be viewed here (I think I accidentally sent you the link from my local machine):
    http://www.designbymarianne.com/CHINMAN_LARGER_SITE/index.html

    Marianne

  25. Some Guy Who Cares

    Not to be rude here on Soh’s blog but I can clearly see why he puts a disclaimer

    “Please note: This tutorial requires basic knowledge of CSS and jQuery. For best results, please be sure to learn the proper foundations before attempting to take this tutorial. Learn one step at a time :-)”

    because there are so many people who take these tutorials without knowing anything about css or js. Marianne do you know what margin: 0 auto; does? It centers things. So if you want it on the left you should float: left. You should really go back and learn CSS before learning more advanced things.

  26. Marianne Ingrid Moner

    To ‘some guy who ‘cares’:

    Yep, pretty rude. I tried that and it didn’t work. How much do YOU know? Clearly nothing about keeping quiet if you’re not the one being asked for some assistance. It’s funny, some people really need to feel ‘big’ by making assumptions and tossing insults. Shame. I notice you’re anonymous, big surprise. Please don’t ruin this site for people. If he can’t, or doesn’t have the time to provide insight beyond what you have attempted that’s fine, but your post adds nothing.

  27. crusher

    good,i like it

  28. Palak Soni

    Good simple toggle.
    thank you for you share !!!!!!! :)

  29. nico

    hi soh…
    what’s the font you use for the on of ur sub header.
    such the one of the comment form. “SPEAKYOURMIND”
    It looks cool.. hope you’d like to share…
    thx

  30. Yocaro

    Wow pretty amazing what you have done to your new site.. Great layout and everything! Keep it up! :)

    - iMediaGFX -

  31. joe

    Sorry but can’t help to add. WOW (@ your floating nav menu) *Two Thumbs Up*

  32. Martyn

    Great stuff!

    How can i do this though?

    I want to have all the items closed by default until clicked, at the moment i have the first content slider open, but wish for them all to be closed?

    Thanks

  33. Fish

    Just brilliant. Awesome tutorial. Here is one of the templates where I have used it.

    http://wantedtemplate.blogspot.com/ (sidebar)

    Yes, it is hosted on blogger. This just goes to show how brilliant is the man who explained it so well that I flawlessly implemented on blogger.

  34. sivaranjan

    Loved the post.
    I am taking the liberty of adding a reference to your article on my CSS aggregator site. Do let me know if you are ok with this.

  35. Mark

    Very nice! I’m curious: is there a straightforward way to set the default open block to be other than the first one?

  36. jo

    its great…please i need one tab action….its not closed in a open single tab…..can give me a solution

  37. Oswaldo Goite

    It’s… It just… The fact is…. MAN!… f*(k! YOU RULE! It’s awesome! Thanks!

  38. Mark

    Figured it out. In the jquery calls replace:
    $(‘.acc_trigger:first’).addClass(‘active’).next().show();

    with (to display the second block open by default):
    $(‘.acc_trigger::nth(1)’).addClass(‘active’).next().show();

    Replace 1 with 2 for the third block, and so on (it’s zero indexed). Just had to poke through the jquery code a bit to see what functions were defined. Cool stuff!

  39. Mark

    Oh, the “::” is a typo, but it will still work. It’s supposed to be just “:”

  40. Mark

    Martyn, to answer your question, just remove this jquery call:

    $(‘.acc_trigger:first’).addClass(‘active’).next().show(); //Add “active” class to first trigger, then show/open the immediate next container

    All blocks will start out hidden because of this previous line:
    $(‘.acc_container’).hide(); //Hide/close all containers

  41. junkfoodjunkie

    anyone can help? how to create a multiple accordion in the same page? em trying to put accordion to multiple DIV content..

  42. lucas sosa

    Thanks for this great Tutorial it came in very handy for a noob like me your
    also i needed to m make the accordion tabs liquid so they wood stretch across the with of the page, with one of your other tutorials (Liquid & Color Adjustable CSS Buttons) i was able to accomplish this task.

    for the person above me if you want to to put multiple accordions in the same page all you have to do is put this html
    Web Design & Development

    code in what ever div you want at least this is how it worked for me.
    once again thank you for your tutorials they are real helpful

  43. David

    Dude you have some awesome designs. You’re my hero. haha

  44. lalaland

    If you have a ton of content inside each accordion, how do you make it so when you open them the focus stays on the top of the one you clicked rather than it opening halfway in the accordion and then you need to scroll up to get to the beginning of that particular one? Know what I mean? :)

  45. Jens

    Thank you for that tutorial

  46. Draco

    Hey!Awesome tutorial, its working just fine but I got a question, have u tried using this same accordion menu but with this extra add-on:?

    The first link “Web Design & DEvelopment” if you click on it,it won’t hide unless you click on another link, is it possible to hide it ? so you can see only the main links without showing the content UNLESS u click on it?
    Hope I explained myself

  47. Andrew

    Thanks for the tutorial, really enjoyed it. Is there anyway I can activate each of the panels from a remote sub menu? I’m building a site at the moment that requires an accordion effect, but that in addition to the links in each title bar, the ability to operate the accordion from a seperate nav menu of the same headings. Any help appreciated.

  48. Cedric

    Draco,

    If you want to be able to hide active content by clicking on it, just add this code.

    else {
    $(this).next().slideUp()
    }

    right after before the return false statement.

    Complete script looks like this for me

    $(document).ready(function(){

    //Set default open/close settings
    $(‘.acc_container’).hide(); //Hide/close all containers
    $(‘.acc_trigger:first’).addClass(‘active’).next().show(); //Add “active” class to first trigger, then show/open the immediate next container

    //On Click
    $(‘.acc_trigger’).click(function(){
    if( $(this).next().is(‘:hidden’) ) { //If immediate next container is closed…
    $(‘.acc_trigger’).removeClass(‘active’).next().slideUp(); //Remove all .acc_trigger classes and slide up the immediate next container
    $(this).toggleClass(‘active’).next().slideDown(); //Add .acc_trigger class to clicked trigger and slide down the immediate next container
    }
    else {
    $(this).next().slideUp()
    }
    return false; //Prevent the browser jump to the link anchor
    });

    });

  49. Pravin

    thanks……! it’s relay use fool Accordion tabs ……….. Thank You Once-again

    ………………………:)

  50. Lelka

    Hi, thanks for this tutorial !
    Can someone tell me how to change the color of the “h2 tag” please ?

    This is what i did to test :

    h2.acc_trigger a {
    color: black;
    text-decoration: none;
    display: block;
    padding: 0 0 0 45px;
    }
    h2.acc_trigger a:hover {
    color: yellow;
    }

    but it didn’t work. The “Web Design & Development” still have the dark grey color !

    An idea ?

  51. Jim Summer

    Hi Soh,
    Man… I love your site! I haven’t even read this tut yet, just wanted to say how much I like your use of CSS sprites for your headers – nice!
    OK, now I will go back and read this tut :~)
    Keep up the GREAT work!
    Thanks!
    ~ Jim

  52. Lelka

    Please, someone can answer my question ?

  53. Lith

    hi everybody!
    I did all the steps but i still have just a div with text but no accordion menu!
    Someone please can help?

  54. LITH

    Thank you so much, it works for me :)
    Now i’m trying to add some images

    Peace

  55. Sagar Ranpise

    This is really helpful, learned a lot from it. Thanks a lot for sharing!

  56. Tan

    Thanks… great website design too!

  57. Ben Johns

    I am pretty new to jQuery and learning how to use it – thanks for the great Tutorial. I was wondering if there was a way to modify the code to have all “accordions” closed by default (as opposed to having he first one forced open) without drastically modify the code… Thanks for any assistance you may be able to provide.

  58. Ben Johns

    Cedric (or any of you other jQuery wizards),
    I am using icons similar to those in the demo to identify that an accordion is open or closed. I tried using your fix, and it seems that the headings are now indeed closing on click, but the “arrow” is not changing orientation from “open” to “closed”. It only changes once I click on a different accordion header. Do you know if there is a solution for this?

  59. Deepak Kaletha

    Another great CSS3 tutorial, i like it!

  60. Mohamed Hassan

    Hi, best step by step tutorial. Cheers mate.

    Just one question though. Where are you replacing the acc_trigger background image?

    Because when you the acc_container is hidden it displays a “play button” icon. And when the acc_container is displayed, it displays an “upside down pyramid”.

    Thanks.

  61. JON-JON

    HI, I LIKE THE EFFECT HOWEVER COULD YOU BE SO KIND AS O TELL US AND SHOW SPECIFICALLY WHAT EACH IMAGE LOOKS LIKE THAT IS IN THE CSS OTHERWISE IT LEAVES US GUESSING A BIT.

  62. luke jordan

    Mohamed Hassan, hope thiz helpz… h2.active {background-position: left bottom;}

  63. Utilities Savings

    Great tutorial… was finding the built-in accordion function transitions rather horrible. This solved it perfectly! Great work!

  64. manu3l9816

    Do you think it could be possible to create this as a wordpress widget?

  65. Jason Corbett

    I’m not sure if this was already asked in the comments, I tried reading them all but there are a truckload.

    Everything is working fine except when I maximize/minimize one of the blocks it makes the rest of my page (eg. footer) jump up a little bit with it.

    I’m sure there is an easy fix to this I just can’t figure it out.

    Thanks in advance!

  66. Ashwin

    Awesome article ! Thank you very much. Is it possible to share the code ? I tired down loading the page but it did not download all the images. And the blue play button on the accordion.

    Thanks,
    Ash

  67. Mary Beth Seacott

    Great tutorial! Love it!

    @ Ben Johns: I had the same issue, but resolved it.
    Just add “removeClass(‘active’).” to the else statement so it reads as follows:

    else {
    $(this).removeClass(‘active’).next().slideUp()
    }

    Hope this helps!

  68. Adeyemi

    Best vertical accordion out there……..and thanks for a great tutorial. Please how I can cross link the the panels. Is there any way to create a nav that control the accordion. Thanks for you help.

  69. Jason Corbett

    Can someone please reply to my question above?

    My footer is moving when the boxes are opened. I can’t figure out how to stop this from shifting my page around.

    Thanks!!

  70. Donovan

    Thanks for fix on the skipping bug. That was driving me nuts (and I tried a fixed width everywhere but the container… doh!)

  71. Fred

    It works perfectly, thank you :)

  72. Peter

    This site is awesome!
    Thank you very much!

  73. Iman Mahdavi Doost

    WoW : this is funk :o OMG

  74. JonasCur

    Your site is an inspiration! Great content and tutorial. Really good way on explaining THE steps. Definitely bookmarking your site as one of the best. Thank you very much.

  75. fanggaofeng

    Thank you for your share!Everything is working fine except when I maximize/minimize one of the blocks it makes the rest of my page (eg. footer) jump up a little bit with it.

  76. stone crusher

    My footer is moving when the boxes are opened. I can’t figure out how to stop this from shifting my page around.
    Thank you!

  77. Jessie

    Excellent tutorial, thank-you so much!

    One small question, how do i get 2 accordions working on the same page?

    This is what i have… mind you i’m a noob at jquery so please be patient!
    //Accordion Set default open/close settings
    $(‘.acc_container, .acc_container2′).hide(); //Hide/close all containers

    //On Click
    $(‘.acc_trigger, .acc_trigger2′).click(function(){
    if( $(this).next().is(‘:hidden’) ) { //If immediate next container is closed…
    $(‘.acc_trigger, .acc_trigger2′).removeClass(‘active’).next().slideUp(); //Remove all .acc_trigger classes and slide up the immediate next container
    $(this).toggleClass(‘active’).next().slideDown(); //Add .acc_trigger class to clicked trigger and slide down the immediate next container
    }
    else {
    $(this).next().slideUp()
    }
    return false; //Prevent the browser jump to the link anchor
    });

    Obviously i have the .acc_trigger2 in my styleSheets and on the markup of the second accordion i’m wanting to display.

    Ta
    Jes

  78. Carl

    Thanks! This had greatly helped me set-up CSS.

    I also like the way you set up the code!

    Great Blog!

    Thanks a million again!

  79. symons cone crusher

    It’s great tutorial and your technique is so cool.
    Well done go ahead.

  80. Hendry

    Hmm >..< I have done all same like your instruction..

  81. Hung Bui

    Thanks for sharing this. We have made use of it on our website.
    http://walkit.com/walking-events-and-tours/list-your-event/

  82. Crusher

    Thank you for your share.

Speak Your Mind...

Post HTMLNeed to Post HTML Code? Use Postable to post code friendly html. *Wrap all html code in <pre></pre> tags.
Post HTMLNeed to Keep Updated with Comments? Subscribe to comments now.

CSS Gallery