An accordion is usually associated with FAQ areas. If printed to the page, FAQs could stop users from finding the answers they’re after due to all the text they’re presented with.
That’s a good argument as they show a simple outline of the content. Imagine browsing an FAQ and you had to scroll all the way down through loads of sections to find the answer, it would be a painful. If you could simply scroll the titles and have the content hidden, it would allow you to scan much faster, therefore giving a better experience.
You might also like: Creating Tabs with HTML, CSS & jQuery
When coding up components I like to follow the BEM structure. Some of you will notice it’s not actual BEM. That’s because I follow a basic principle which uses nested-naming. For example, the entire element has an .accordion-section
inside it, which is then followed by an .accordion-section-title
.
This approach can have its drawbacks, yet I’ve found it to be sustainable on larger projects because it makes me think about how many elements I’m nesting and if it’s necessary.
It also keeps my Sass organised, therefore it avoids too much nesting and keeps things readable.
<div class="accordion">
<div class="accordion-section">
<a class="accordion-section-title" href="#accordion-1">Accordion Section #1</a>
<div id="accordion-1" class="accordion-section-content">
<p>Mauris interdum fringilla augue vitae tincidunt. Curabitur vitae tortor id eros euismod ultrices. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nulla mi, rutrum ut feugiat at, vestibulum ut neque? Cras tincidunt enim vel aliquet facilisis. Duis congue ullamcorper vehicula. Proin nunc lacus, semper sit amet elit sit amet, aliquet pulvinar erat. Nunc pretium quis sapien eu rhoncus. Suspendisse ornare gravida mi, et placerat tellus tempor vitae.</p>
</div><!--end .accordion-section-content-->
</div><!--end .accordion-section-->
</div><!--end .accordion-->
There are a few things going on here. First of all, see the overflow:hidden;
on the main element. This is done to give the rounded corners effect on the sections, yet stop things hanging over the edge.
I’ve used comments to indicate where any type styling is placed. I do this on all projects to keep things organised. In Sass, I write it as // Type
. When you leave a code comment in a Sass file with the two slashes it doesn’t show up in the compiled CSS.
/*----- Accordion -----*/
.accordion,
.accordion * {
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
.accordion {
overflow:hidden;
box-shadow:0px 1px 3px rgba(0,0,0,0.25);
border-radius:3px;
background:#f7f7f7;
}
/*----- Section Titles -----*/
.accordion-section-title {
width:100%;
padding:15px;
display:inline-block;
border-bottom:1px solid #1a1a1a;
background:#333;
transition:all linear 0.15s;
/* Type */
font-size:1.200em;
text-shadow:0px 1px 0px #1a1a1a;
color:#fff;
}
.accordion-section-title.active,
.accordion-section-title:hover {
background:#4c4c4c;
/* Type */
text-decoration:none;
}
.accordion-section:last-child .accordion-section-title {
border-bottom:none;
}
/*----- Section Content -----*/
.accordion-section-content {
padding:15px;
display:none;
}
$(document).ready(function() {
function close_accordion_section() {
$('.accordion .accordion-section-title').removeClass('active');
$('.accordion .accordion-section-content').slideUp(300).removeClass('open');
}
$('.accordion-section-title').click(function(e) {
// Grab current anchor value
var currentAttrValue = $(this).attr('href');
if($(e.target).is('.active')) {
close_accordion_section();
}else {
close_accordion_section();
// Add active class to section title
$(this).addClass('active');
// Open up the hidden content panel
$('.accordion ' + currentAttrValue).slideDown(300).addClass('open');
}
e.preventDefault();
});
});
It’s a best practice to outline the code you’re going to write before you start, especially with something like JS.
Here is the code we need and in this case, we would write it out in a procedural fashion, then move on to making it more modular. As a result, we get the following two examples:
$(document).ready(function() {
function close_accordion_section() {
// Close everything up
}
$('.accordion-section-title').click(function() {
// Grab current anchor value
var currentAttrValue = $(this).attr('href');
// Open and close here
});
});
$('.accordion-section-title').click(function() {
// Grab current anchor value
var currentAttrValue = $(this).attr('href');
$('.accordion .accordion-section-title').removeClass('active');
$('.accordion .accordion-section-content').slideUp(300).removeClass('open');
$(this).addClass('active');
$('.accordion ' + currentAttrValue).slideDown(300).addClass('open');
});
From there we can move on to the modular version of the code by adding functions and so on:
function close_accordion_section() {
$('.accordion .accordion-section-title').removeClass('active');
$('.accordion .accordion-section-content').slideUp(300).removeClass('open');
}
In conclusion, they can be very useful, as I said in the intro. However, be aware they should only be used in cases where they’re beneficial, as is the case with any component.
By improving your code as you go, you’ll learn to just make it modular from the start.
If you have any questions or comments just leave a comment below!
You might also like: Create a Fading Popup Modal with jQuery
Join the newsletter to get the best articles, tutorials and exclusive freebies every two weeks.
Awesome
April 9, 2019 at 8:04 pm
Really great! The best script / solution out there! Thanks so much Seb!
Subhrahtoti
December 15, 2017 at 4:00 pm
I have one Panel having two child panel which is showing by default.
My requirement is to show only one different panel under main panel if java variable showTwopanel =true else show only one panel.
Kate
October 17, 2017 at 10:43 am
Michael
October 16, 2017 at 6:31 am
I may be missing something but the class “open” doesn’t appear in either the markup and is not defined in the CSS. Could someone please explain how that works. Thanks.
Brandon
September 28, 2017 at 1:32 pm
For those wondering (like me!) how to get one accordion section to be open on initial page load, take Alex’s improved JS and add a couple lines to the end:
jos
September 26, 2017 at 7:04 pm
Opens the first!
$( document ).ready(function() {
$(‘a[href$=”#accordion-1″]’).click();
});
Robert
January 25, 2018 at 6:11 am
your code worked!!!
Nilam
May 11, 2017 at 2:00 pm
Hello
I want show default open one accordion when page is load .How I can do this.
please as soon as possible.
Thank you.
Mike
March 20, 2017 at 2:34 pm
How could I open one ore more accordions by default?
Thanks in advance
Alex
March 9, 2017 at 10:33 am
Hi, everybody!
Some impovements.
If you don’t want to manually assign id=”accordion-1″, id=”accordion-2″, etc… to the DIV with classname=”accordion-section-content”.
Just take this script:
Florin
September 18, 2018 at 9:39 pm
THANK YOU FOR THIS!
Rajesh
October 17, 2016 at 10:13 am
How to get the first accordion element open by default??
anmol
July 22, 2017 at 11:23 am
Sir Please tell me how i could 1st accordian be opende by default when page is refreshed
Jen
October 2, 2016 at 5:51 pm
I’ve been trying to figure out a way to make the default of the accordion as open. Is there a way?
Dave
September 8, 2016 at 8:46 pm
Hey everyone,
I, too, was confused about the sections opening and closing together. To fix this you have to rename your accordions in your HTML numerically. Example:
On the next accordion rename your href and div id to accordion-2. That’s it. Hope that helped!
Victor M. Barba
August 21, 2016 at 10:38 pm
Hello:
I hope you can help me. I would like to make some improvements to my web-site. songnes.com How much would you charge me, to make a contact form that actually “works” with only HTML and CSS. If you my web-site I don’t have a contact form.
I hope I hear back from you… Thanks
Victor
anu
August 9, 2016 at 10:20 am
Thanks for the demo . I should have only one accordian opened at a time ,it does that job ..but when i try to close the current accordian ,it toggles instead of closing the content ..help required pls !!
Adrien Rosi
June 23, 2016 at 11:26 am
An other way :
Paul
June 10, 2016 at 1:20 pm
Can you add a expand all and collapse all link with function to the accordion?
Thank you, great tutorial.