Creating Accordion with Javascript

In this blog, I am going to create an accordion by using native javascript. No library like jQuery is required. JQueryUI has a built-in accordion component, which is great to use. But as a responsible developer, we should also know how to create one with pure javascript. If you don’t know what accordion is then look jquery one here.

Let’s break down the component into smaller steps.

  • Accordion contains list of panels.
  • Each panel has two component, header & body.
  • Header component of all the panel is always visible.
  • A panel can be expanded or collapsed.
  • When a panel is expanded, it’s body component becomes visible.
  • Only one panel can be expanded at a time.
  • When other panel is expanded, last panel’s body component hides.

Let’s build the component with small steps.

Step1 :- Design basic HTML

Let’s create some basic html which creates list of panels with header & body.

<div id="accordion">
<div class="panel"> <!-- first panel -->
<div class="acc-header">header1</div>
<div class="acc-body">body of panel 1</div>
</div>
<div class="panel"> <!-- second panel -->
<div class="acc-header">header2</div>
<div class="acc-body">body of panel 2</div>
</div>
<div class="panel"> <!-- third panel -->
<div class="acc-header">header3</div>
<div class="acc-body">body of panel 3</div>
</div>
</div>

Above html contains list of panel. Each panel has header and body item. Currently everything is visible.

Step2 :- Define some CSS to handle visibility

Let’s create two CSS classes to define the visibility of the body.

/** This class will hide all the body by default **/
#accordion .acc-body{
display : none;
}
/** This class will show the body if it has "active" parent class. "active" class will be added to panel div **/
#accordion .active .acc-body {
display : block;
}

By default, we want to hide all the panel’s body as per the requirement. Now we need to show only expanded element at a time. We will add active class in the panel div to make the body visible.

Step3 :- Using CSS in the HTML

After adding CSS in our HTML, the code will be

<div id="accordion">
<div class="panel active"> <!-- first panel -->
<div class="acc-header">header1</div>
<div class="acc-body">body of panel 1</div>
</div>
<div class="panel"> <!-- second panel -->
<div class="acc-header">header2</div>
<div class="acc-body">body of panel 2</div>
</div>
<div class="panel"> <!-- third panel -->
<div class="acc-header">header3</div>
<div class="acc-body">body of panel 3</div>
</div>
</div>

Now all the panel’s body is hidden except the first one. We created our basic accordion component. We need to use some javascript to make it fully functional.

Step4 :- Adding click events

We will add click event on each panel, which will change the visibility of the panel.

function initAccordion(accordionElem){

//when panel is clicked, handlePanelClick is called.
  function handlePanelClick(event){
showPanel(event.currentTarget);
}
//Hide currentPanel and show new panel.  

function showPanel(panel){
//Hide current one. First time it will be null.
var expandedPanel = accordionElem.querySelector(".active");
if (expandedPanel){
expandedPanel.classList.remove("active");
}
     //Show new one
panel.classList.add("active");
  }
  var allPanelElems = accordionElem.querySelectorAll(".panel");
for (var i = 0, len = allPanelElems.length; i < len; i++){
allPanelElems[i].addEventListener("click", handlePanelClick);
}
  //By Default Show first panel
showPanel(allPanelElems[0])
}
initAccordion(document.getElementById("accordion"));

JS Fiddle link here

initAccordion function is defined to initialize the accordion component. It puts a click event on each panel. When a panel is clicked, it removes the active class from the current active panel and adds it to the new panel. By default, it makes the first panel as active. We can make any panel as active by default by passing the panel element to the showPanel function.

We have created our accordion successfully. This is just a very basic model of accordion but it covers the main functionality.

We can make it more fancy by adding nice css styles, animation and icons. Also, we can make it more performance oriented by implementing event delegation & caching current active elements. Refer my blog on events to learn about events in detail.