Today we’re going to code some responsive jQuery accordions.
Accordions are an extremely popular UI element on most websites and applications, especially for content rich sites. However, most accordions require that only one accordion can be opened at a time. I’m going to show you how to code an accordion group that allows each accordion to be opened independently of it’s siblings.
HTML
Our markup starts with a parent .accordion-container div. Inside that div we’ll have an anchor tag with class of accordion-toggle and another child div with the accordion-content class. All of your content – images, text, etc. – should go inside .accordion-content.
Note: Inside our .accordion-toggle link we have a span and an i tag. These are used to toggle the plus/minus icon (using Font Awesome icons). Font Awesome is a great resource for icons – check it out if you haven’t used it already.
<div class="accordion-container"> <a href="#" class="accordion-toggle">Rome <span class="toggle-icon"><i class="fa fa-plus-circle"></i></span></a> <div class="accordion-content"> <img src="images/italy-thumb_rome.jpg" /> <p>...</p> </div> <!--/.accordion-content--> </div> <!--/.accordion-container--> <div class="accordion-container"> <a href="#" class="accordion-toggle">Florence <span class="toggle-icon"><i class="fa fa-plus-circle"></i></span></a> <div class="accordion-content"> <img src="images/italy-thumb_florence.jpg" /> <p>...</p> </div> <!--/.accordion-content--> </div> <!--/.accordion-container--> <div class="accordion-container"> <a href="#" class="accordion-toggle">Venice <span class="toggle-icon"><i class="fa fa-plus-circle"></i></span></a> <div class="accordion-content"> <img src="images/italy-thumb_venice.jpg" /> <p>...</p> </div> <!--/.accordion-content--> </div> <!--/.accordion-container-->
CSS
Our CSS is pretty simple. We’ll hide the .accordion-content divs using display:none and then toggle them using jQuery. Feel free to adjust the padding, colors, etc., for your toggle links and accordion content.
We’ve also got a CSS3 media query to adjust the accordion-content padding and overflow properties when in mobile view, thus keeping our promise on these accordions being responsive 🙂
.accordion-container { width: 100%; margin: 0 0 20px; clear: both; } .accordion-toggle { position: relative; display: block; padding: 20px; font-size: 1.5em; font-weight: 300; background: #999; color: #fff; text-decoration: none; } .accordion-toggle.open { background: #333; color: #fff; } .accordion-toggle:hover { background: #666; } .accordion-toggle span.toggle-icon { position: absolute; top: 9px; right: 20px; font-size: 1.5em; } .accordion-content { display: none; padding: 20px; overflow: auto; } .accordion-content img { display: block; float: left; margin: 0 15px 10px 0; max-width: 100%; height: auto; } /* media query for mobile */ @media (max-width: 767px) { .accordion-content { padding: 10px 0; overflow: inherit; } }
jQuery
We’ll use jQuery to do 3 things:
- Toggle the accordion link “open” class
- Toggle the accordion content (hide & show)
- Change the accordion link plus/minus icon
It’s important to note that we use jQuery’s .next method, which works because our .accordion-toggle link and .accordion-content div are siblings. So pay close attention to your nesting.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { $('.accordion-toggle').on('click', function(event){ event.preventDefault(); // create accordion variables var accordion = $(this); var accordionContent = accordion.next('.accordion-content'); var accordionToggleIcon = $(this).children('.toggle-icon'); // toggle accordion link open class accordion.toggleClass("open"); // toggle accordion content accordionContent.slideToggle(250); // change plus/minus icon if (accordion.hasClass("open")) { accordionToggleIcon.html("<i class='fa fa-minus-circle'></i>"); } else { accordionToggleIcon.html("<i class='fa fa-plus-circle'></i>"); } }); }); </script>
Conclusion
As I mentioned earlier, these accordions are unique from most framework accordions (Bootstrap, jQuery UI, etc.) because they don’t require only one accordion to be opened at a time. Thanks for reading – I hope these are helpful in your projects!
What is fa fa-plus fa-minus class i did not get it
Muhammed, those classes are used for Font Awesome icons. Take a look at Font Awesome to learn more:
http://fortawesome.github.io/Font-Awesome/icons/
nice. extremely helpful and clean. thanks 🙂
when we click the next accordin tab, the previous one should automatically close, how to achieve that
No, that’s NOT how these are supposed to work. You obviously didn’t read the tutorial. These accordions are meant to stay open. If you want accordions that only keep one open you can use Bootstrap or jQuery UI.
Great tutorial, thanks! I had an issue with the <767px where the toggle would display over the content when the sections were opened (i.e. the toggles didn't move and the content would open/display terribly), but all fixed by changing the overflow to "hidden".
Thanks!
I’ve got the plus/minus icons to switch but .accordion-content won’t toggle with it. Any idea why?
Hi Ali. Thank you so much, this is exactly what I’ve been looking for! So many developers don’t explain things in layman’s terms. Keep up the good work!
Glad it was helpful!
Thank you, I nested your slideout menu and accordion and mashed it up… menu looks awesome! I can now fit all my web controls within one a s smart phone windw.
Thanks a lot! I’ve used this code, but now they want it to close the previous one. I know it’s not made for that but is there a line of code that could maybe change that?
Thanks!
Hey Mateo,
If you need the previous one to close then you’re better off using the Bootstrap Accordions:
http://getbootstrap.com/javascript/#collapse-example-accordion
They are designed to work that way, and it’s pretty easy to over-ride their CSS to make them look how you want.
Hope that helps!
Thanks!
how do i post more than one content in one menu???
Is there a way to have the top accordion (or any other) be open by default?
hey, thanks a lot! Is there any way scrolling to the top of the clicked accordion?
How can I show opened first accordion-content
did you ever get help with this question? I have the same one.
Hi, and thanks! I use the code on one of my sites, but the link seems to interfere with other link-classes on the site. Do you have a solution for a basic level css-coder that can solve that?