Building an FAQ Accordion with JQuery

by J.V Krakowski

Long, drawn-out content is a pet peeve of mine. After a decade of evaluating websites, does anyone blame me? When you imagine creating websites, endless scrolling isn’t something you think will be a problem. I learned to appreciate those “back to top” buttons if nothing else.

I acknowledge on a minor level that long content is sometimes unavoidable. Most help sections are among those exceptions. In those cases, there’s such a thing as an accordion effect to help condense content into a consumable format. Today, we’re going to learn how to build a simple one with jQuery.

The tools you’ll be needing are:

  • jQuery 3.5.1
  • Code Editor
  • Dummy content

To set up your work environment, we’re going to create a folder on your desktop. You can name it anything you want, but it would be best to keep it simple. It would be a blank folder on your desktop.

I like to open the folder and then minimize it on my taskbar. It’s a personal preference, so you can do whatever you want at this point. Right now, we’re going to open our code editor to create the HTML that will display the jQuery code we make.

I use several different editors, and it doesn’t matter what you choose. Since this isn’t a tutorial on how to code HTML, I’ll slap the code right here:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="style.css">
    <link rel="stylesheet" type="text/css" href="normalize.css">
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <script src="ask.js"></script>
    <meta charset="UTF-8">
    <meta name="description" content="Free Web tutorials">
    <meta name="keywords" content="HTML,CSS,XML,JavaScript">
    <meta name="author" content="John Doe">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ask | Built with JQuery</title>
</head>
<body>
    <div class="wrapper">
        <h1>Ask &mdash; Demo</h1>
        <p>A basic, no frills FAQ built with jquery.</p>
        <input class="open" type="button" value="Open All">
        <dl class="questions">
            <dt>Question 1</dt>
            <dd>Answer</dd>
            <dt>Question 2</dt>
            <dd>Answer.</dd>
        </dl>
    </div>
</body>
</html>

If you look at the head section, you’ll notice several essential bits of code. The code tells the browser where to find the stylesheets. The

Everything between the wrapper class will be affected by our jQuery code. For this tutorial, you can copy and paste it into your index file. Speaking of which, you need to create an index file and save it to your folder.

It should look like this:

[img]

Now, we’re going to concentrate on creating the script that will make this accordion work. Here is the full code:

$(function () {
  var Speed = 800;
  $('.questions dd').hide();
  $('.questions dt').click(function () {
    $(this).next(".questions dd").slideToggle(Speed);
    $(this).toggleClass("expanded_img");
  });
    $('.open').click(function (){
        $('.questions dd').slideToggle('.questions dt');
        $('.questions dt').toggleClass("expanded_img");
        $('.open').val('Open All');
        $('.open').toggleClass('close');
        $('.close').val('Close All').removeClass('.close');
    });
});

The above code is simple, and I purposefully made it that way. if you look at the first line of code, you’re going to see this:

$(function() { ... });

That code is the short-hand for the following:

$(document).ready(function() { ... });

Both of them ensure that the script is loaded once the DOM elements are ready to be used. The phrase “DOM elements” refers to the HTML on a web page. We need it to operate that way because the script won’t work correctly if the DOM elements aren’t loaded properly.

The next bit of code looks like this:

var Speed = 800; 

In that line, I’m declaring a variable called “Speed.” It will tell the script how quickly the accordion should open and close. Speaking of which, here is the next bit of code:

$('.questions dd').hide();
  $('.questions dt').click(function () {
    $(this).next(".questions dd").slideToggle(Speed);
    $(this).toggleClass("expanded_img");
  });

We’re telling the script to find the class “questions” and hide the answer portion of it. The following code makes the question a clickable link so that it will reveal the answer below it. The last bit of code appends the class “expanded_img” to the DIV.

The class appended to the DIV is controlled by our stylesheet. It calls the icons that indicate the closed or open status of an accordion item.

The next portion of our code looks like this:

$('.open').click(function (){
        $('.questions dd').slideToggle('.questions dt');
        $('.questions dt').toggleClass("expanded_img");
        $('.open').val('Open All');
        $('.open').toggleClass('close');
        $('.close').val('Close All').removeClass('.close');
    });

When I was coding the accordion, I wanted an open and close icon next to the questions. The above code makes that happen repeatedly. The code that calls the “open” class is referring to the “Open All” button.

The button will say “Open All” if the accordion is closed. Once you click the button, the text becomes “Close All.” The code doesn’t interfere with the click function of the question itself.

The code [val] refers to the text of the button itself. Changing the value of that code will change the text that appears on the button.

Now, all of this is going to look strange until we add code to our stylesheet. If you refer back a few paragraphs, you’ll notice that I linked to a stylesheet called “normalize.” That is the work of a person named Nicolas Gallagher. You can check out his Github here.

It isn’t necessary to add the normalize stylesheet. The only thing it does is unify how different browsers display the code. I like adding it to all my projects as a good habit.

The stylesheet that I coded looks like this:

body {
    font-size: 16px;
    font-family: Helvetica, Arial, sans-serif;
    background: #ecf0f1;
    padding: 10px;
}

.wrapper {
    width: 75%;
    max-width: 1140px;
    margin-left: auto;
    margin-right: auto;
}

h1 {
    text-align: center;
}

/* Quetions */

dl.questions {
    background: #DCE3E5;
}

dl.questions dt {
    background: #E8ECEE url('plus.svg') right center no-repeat;
    background-size: 22px;
    background-origin: content-box;
    cursor: pointer;
    padding: 15px;
    border-bottom: 1px solid #DCE3E5;
}

dl.questions dd {
    padding: 15px;
    background: #DCE3E5;
}

dl.questions .expanded_img {
  background: #E8ECEE url('minus.svg') right center no-repeat;
  background-size: 15px;
  background-origin: content-box;
  cursor: pointer;
}

The stylesheet adds aesthetics to the web page. It’s essentially personal preference, and it has little to do with jQuery itself. Altering the code here changes the way it appears on the web page.

The classes with icon backgrounds are essential. That is how jQuery changes the icon from one to another. However, it can be tweaked to fit your project.

I encourage you to experiment with the code. Playing around with someone else’s code is how many developers learned how to do it themselves. When you handle the code, you’re learning what each section does. You can download this code on github.

Or, you can see a demo of it here.

Back to Previous Page