Building an Accordion with JavaScript and jQuery

In this tutorial we will build a simple accordion with JavaScript and jQuery.

The accordion is a common UI element that allows for content to be displayed and hidden when the user clicks.  It is especially common on FAQ pages.

Requirements:

  1. User must be able to click a heading to show/hide content
  2. Developers must be able to specify which content is shown by default when the page is loaded.
  3. Developers must be able to use any type of html content in the heading and content block.
  4. Only one content block should be open at a time.

Accordion HTML

First we need to write some HTML. For this lesson we will use a simple heading and content block structure. Its pretty basic. We will use classes as our JavaScript selectors so we can use any HTML elements as our heading and content blocks in the future. This will make our script more flexible and reusable.

We will use the custom data attribute to satisfy our second requirement. I will explain this in more detail when we add our JavaScript.

<div class="accordion">
    <h2 class="accordion-label">This is the first heading</h2>
    <div class="accordion-content" data-state="expanded">
       <p>This is some content</p>
    </div>
    <h2 class="accordion-label">This is the second heading</h2>
    <div class="accordion-content">
        <p>This is some content</p>
    </div>
    <h2 class="accordion-label">This is the third heading</h2>
    <div class="accordion-content">
        <p>This is some content</p>
    </div>
</div>

Accordion CSS

These are just some basic css styles for our accordion. This just adds some light borders with slightly rounded corners to our accordion elements. We will hide the accordion content using CoffeeScript to make our content available to users with JavaScript disabled. You can choose to add display: none; to your accordion content depending on your project specifications.

Add the following css to your main css file.

.accordion {
    width: 600px;
    box-sizing: border-box;
}

.accordion-label {
    border-radius: 3px;
    background-color: white;
    width: 100%;
    margin: 5px 0;
    box-sizing: border-box;
    padding: 5px 10px 5px 10px;
    border: 1px solid #ccc;
    font-size: 18px;
}

.accordion-content {
    border-radius: 3px;
    background-color: white;
    width: 100%;
    box-sizing: border-box;
    padding: 5px 10px 5px 10px;
    border: 1px solid #ccc;
}

.accordion-content p {
   font-size: 16px;
}

Accordion JavaScript

So now onto the JavaScript. This is where we build the real functionality of our accordion. Just for better organization and code reuse I would suggest creating a file called accordion.js and adding the code there. This way you can easily use it on future projects. You will also need to add jquery for the accordion to work.

This tutorial does assume some basic JavaScript knowledge.

First lets add our script in a self-invoking anonymous function so that our script doesn’t interfere with other JavaScript code. We will also make sure that we can use $ to mean jQuery by adding $ = jQuery;

(function() {
   var $ = jQuery;
   // accordion script will go here
});

Next lets set up our accordion variables. We only have one more to add, our accordion.

(function() {
   var $ = jQuery,
       accordion = $('.accordion');  
})();

Now we will hide any content that shouldn’t be displayed by default. This is where our custom data attribute is used.

Any content with the data-state attribute set to expanded is displayed while any other content is hidden.

(function() {
   var $ = jQuery,
       accordion = $('.accordion');

   accordion.find('.accordion-content').hide();
   accordion.find('.accordion-content[data-state=expanded]').show();
})();

Now we will add the content toggle function to our script. It works by finding the next element with the .accordion-content class and acting upon it. We need to create the that variable so that we don’t need to access the DOM multiple times. This improves the performance of our script slightly. I usually save a jQuery element as a variable if I am using it more than once.

We use the jQuery slideToggle method so that the content appears to slide up and down.

(function() {
    var $ = jQuery,
        accordion = $('.accordion');

    accordion.find('.accordion-content').hide();
    accordion.find('.accordion-content[data-state=expanded]').show();

    accordion.on('click', '.accordion-label', function() {
        var that = $(this);

        that.next('.accordion-content').slideToggle();
    });
})();

Now we are almost done. We just need to fulfill the last requirement. To do this we add one more line of code.

This line checks for any visible elements with the .accordion-content class and hides them.

(function() {
    var $ = jQuery,
        accordion = $('.accordion');

    accordion.find('.accordion-content').hide();
    accordion.find('.accordion-content[data-state=expanded]').show();

    accordion.on('click', '.accordion-label', function() {
        var that = $(this);

        that.closest('.accordion').find('.accordion-content:visible').slideUp();
        that.next('.accordion-content').slideToggle();
    });
})();

Now you have a basic accordion that you can use in your web development projects. You can take it a few steps further and add some additional features like icons that change based on the accordion-content state or ‘show all’ and ‘hide all’ buttons.

I hope this tutorial was enjoyable and helpful. Look for upcoming JavaScript UI element tutorials.