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;
}
}
}
Slightly more advanced, preventing closing of active panel:
Thanks Chris. I was looking for a simple, lightweight alternative to all that jQueryUI jazz.
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.
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.
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;
});
});
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.
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);
});
whoa never mind.. I didn’t close the tag
Is there a demo of this anywhere?
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 ?
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.
To be able to close an item by clicking on it again just track the last one’s content:
How can I use this with WordPress’ dynamic navigation?
Thanks.
This gives me some more ideas on accordion.
Awesome! just what I was looking for!
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
I did this:
Works for me…
Gr. Bert
Hi,
To avoid the “jump” bug, just add :
position : relative;
on a parent div.Fabrice
position : relative;
on the definition list itself would also do the trick and you that way you don’t need the extra div : )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.
It solved my problem.
Thanks a lot.
Keep rocking…
Simple and effective!
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>
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.
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.
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();
});
});
}
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
Ooops … hope this works :-/
<dd&rt<p&rtTEXT</p&rt</dd&rt
No .. I’m obviously stupid :-/ Antway, just put the P inside the DD :-)
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.
here’s very simple and nice script – http://www.sebastiansulinski.co.uk/demos/jquery-accordion/
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?
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.
great article I using the following code
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.
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
OMG! i got it…. Thanks a ton.
would like to know if you are still answering any of the comments in this thread, simple jquery accordian
thanks
Great, simple, thanks!
Could you help to support cookies and remember open <dt>?
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:
Thanks guys!
Change them to DIV’s and put the lists inside mate. :-)
thank. gracias desde colombia. me sirve muchisimo.
Thanks so much. Really clear article.
Thanks for the tutorial, it really help me a lot.
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?
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.
add position : relative; to .accordion class.. that fixes the jump
I confirm Marz’ fix. Thanks!
Great script..
Is there a way to get the first item in the accordion to be open on page load rather than hiding all?
var allPanels = $(‘.accordion > dd’).hide().slice(1).show();
http://viralpatel.net/blogs/demo/jquery-accordion-menu-example/
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
Remove # from the link tag and use ‘ href=”js:;” ‘ instead.
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
@Josh and @Bacca – You can fix the bounce open and closed with this:
Almost similar with your’s solution, this works for me and i submit it as an alternative solution:
Thanks Davey! this solve when you click on an open tap
Wow Davey, you solved my problem of being able to close each item with just one simple line of code! Genius!
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??
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.
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!
Thanks Davey! That worked great and solved the bounce issue :)
Thank you for this code!
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?
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?
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.
thanks alot mate. your fix works. cheers
This snippet helped me immensely. Thank you for sharing.
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/
This i great!
How do I only show one panel at a time?
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.
I tried this to allow for accordion tabs (dt) to be collapsible once opened:
This is one of the better accordion demonstrations. Nice and clean.
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…!
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
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:
CSS is below. I converted from SCSS. Like I said, I am not a dev/designer so my syntax and probably semanticism SUCKS.
Awesome, this worked perfectly. Thank you for sharing that solution!
Awesome !!! cool code for making a very simple jquery accordion.
god bless you, Chris!
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
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
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
To get the first one to show (previous solution someone posted didn’t work).
I did:
Errr ignore the previous post, it breaks it.
Just add this line below the var allPanels line:
It can be used as fundamental, but not as advanced.
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-
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
@Kevin: if you want to open multiple
dd
elements at once, do this: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:
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.
Your tutorial has converted me into using SASS. Thank you!
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/
Hi how do I build an accordion within an accordion? please help! thanks!
You would use nested lists.
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 ‘&’:
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!
‘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
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;
}
});
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!
If you mean that all of the accordion sections should be closed on start, you can do something like:
var allPanels = $( '.accordion > 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 > dd').first().show();
How would you add the plus minus sign to it?
Thanks!
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’);
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
Thanks for this dude
It has some issues with pagination……it doesn’t work when you go to the next page using pagination.
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.
With promises:
Thanks Chris, this is fantastically lightweight & easily to implement!
Here’s a good full-page horizontal accordion I just finished putting together -> http://codepen.io/dcdev/full/azvGwm/
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.
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?
I have better script:
To nest multiple accordion instances, one inside the other, replace the call to: allPanels.slideUp(); (in the original code) with the line below:
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);
Gracias !!!
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
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!
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,
I’m used this code with “Smooth Scrolling” https://css-tricks.com/snippets/jquery/smooth-scrolling/ to scroll to optimize long panels. Thanks!
I’m using “Tabs – Responsive Tabs with Accordions” plugin and I would love to close all the tabs ONLY in the mobile site (responsive) because it’s showing the first tab by default. I don’t know css or html code so, can anybody help me? I would really appreciate it.
Thanks in advances
Virginia
What if I want to close the opened accordion clicking on it?
$('.accordion-header').on('click', function() {
console.log('clicked!')
allPanels.slideUp();
if(!$(this).next().is(':visible'))
{
$(this).next().slideDown();
}
return false;
});
Love this accordion. Very lightweight and customizable. How would i tweak it for hyperlinks within the hidden sections? Currently, all hyperlinks disappear which i’m assuming is because of the “$(‘.accordion > dt > a’).click(function() {“. How should i alter this to allow for hyperlinks in each section?
Thanks for this super leightweight and easy solution. Many people are putting a 3MB WordPress Plugin into a website instead of using super simple stuff like this, just to achieve the same result. Also a good idea to use dl/dt.
Thanks Chris. It helps me to fix my accordion problem.