Creating a Collapsible Accordion in JavaScript

A collapsible accordion is a popular UI pattern that allows you to display content in a compact and organized manner. It works by showing only one section of content at a time and collapsing or expanding sections when the user interacts with the accordion items. In this tutorial, we'll build a simple collapsible accordion using HTML, CSS, and JavaScript.

Accordion Example

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

1. What You'll Need

To follow along, you'll need:

  • A basic understanding of HTML, CSS, and JavaScript.
  • A text editor (like VSCode, Sublime Text, or any IDE of your choice).
  • A browser to view and test your project.

2. HTML Structure

We'll start by creating the basic structure of the accordion in HTML. Each section of the accordion will consist of a heading and a content container that will collapse or expand when clicked.

<h2>Accordion</h2>
<button> class="accordion">Section 1</button> 
<div class="panel">
   <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button> class="accordion">Section 2</button> 
<div class="panel">
   <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button> class="accordion">Section 3</button> 
<div class="panel">
   <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

Explanation:

  • accordion-container: This holds all the accordion items.
  • accordion-item: Each individual section of the accordion.
  • accordion-header: The clickable button that triggers the collapsing and expanding of the section.
  • accordion-content: The section's content that will be hidden or shown.

3. Styling with CSS

Next, we'll add some CSS to style the accordion and make the transitions smooth when expanding or collapsing the sections.

.accordion {
	background-color: #eee;
	color: #444;
	cursor: pointer;
	padding: 18px;
	width: 100%;
	border: none;
	text-align: left;
	outline: none;
	font-size: 15px;
	transition: 0.4s;
}

.active,
.accordion:hover {
	background-color: #ccc;
}

.panel {
	padding: 0 18px;
	display: none;
	background-color: white;
	overflow: hidden;
}

.accordion-heading {
	padding: 20px 0;
}

Explanation:

  • The .accordion-header has a button-like appearance with padding, a background color, and a hover effect.
  • The .accordion-content is initially hidden using display: none; and will be shown when the section is expanded.
  • To make the transition smooth, we use transition: max-height 0.3s ease-out; for the content's height. We'll dynamically adjust the height in the JavaScript later.

4. Adding Functionality with JavaScript

Now, let's add the JavaScript code to make the accordion interactive. When a user clicks an accordion header, it should expand or collapse the associated content.

var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
   acc[i].addEventListener("click", function () {
      this.classList.toggle("active");
      var panel = this.nextElementSibling;
      if (panel.style.display === "block") {
         panel.style.display = "none";
      } else {
         panel.style.display = "block";
      }
   });
}

Explanation:

  • We add an event listener to each accordion header. When a header is clicked, the accordion-content for that header is toggled (shown or hidden).
  • We use nextElementSibling to access the content that follows the header.
  • We toggle the display property of the content and use the maxHeight property to ensure smooth transitions. The scrollHeight of the content is used to set the maxHeight when the section is expanded.

5. Final Enhancements (Optional)

You can add a few more enhancements to the accordion:

Closing Other Sections When One is Opened

Accordion title 1

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellat maiores temporibus impedit consectetur id sint modi, quo sunt facere ipsum beatae? Natus quisquam iusto similique repudiandae adipisci in, voluptas maiores, molestiae blanditiis at consectetur cupiditate voluptates ducimus saepe cumque. Error nulla possimus a eligendi facere officiis soluta aliquam est quis molestias nam, officia adipisci, porro ut fugiat? Ipsam, odio fugiat!

Accordion title 2

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellat maiores temporibus impedit consectetur id sint modi, quo sunt facere ipsum beatae? Natus quisquam iusto similique repudiandae adipisci in, voluptas maiores, molestiae blanditiis at consectetur cupiditate voluptates ducimus saepe cumque. Error nulla possimus a eligendi facere officiis soluta aliquam est quis molestias nam, officia adipisci, porro ut fugiat? Ipsam, odio fugiat!

Accordion title 3

Lorem ipsum dolor sit, amet consectetur adipisicing elit. Officia itaque harum explicabo beatae eos illum, amet reiciendis eaque expedita consectetur quo, velit magnam sunt doloribus dolore laudantium cum rem, fuga aut quidem ipsa libero quasi? Quasi ipsam unde ratione possimus illum alias, voluptas ullam soluta vel repudiandae perspiciatis. Nam at rerum eum excepturi? At facilis tempore temporibus consequatur in consequuntur voluptatum molestiae, vel a omnis, cum exercitationem ullam nemo ut!

If you want only one section to be open at a time, you can modify the JavaScript to close other sections when a new section is clicked.

<!DOCTYPE html> 
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>>
        @import url("https://fonts.googleapis.com/css?family=PT+Sans&display=swap");
        .accordion {
            width: 100%;
            max-width: 500px;
            overflow: hidden;
            margin-top: 2px;
        }

        .accordion-header {
            position: relative;
            padding: 20px;
            cursor: pointer;
            display: flex;
            justify-content: space-between;
            background-color: #777;
            font-family: "PT Sans", sans-serif;
        }

        .accordion-content {
            padding: 0 20px;
            max-height: 0;
            overflow: hidden;
            will-change: max-height;
            transition: all 0.25s ease-out;
            font-family: "PT Sans", sans-serif;
        }

        .accordion h4,
        .accordion p {
            margin: 0;
            line-height: 1;
        }

        .accordion h4 {
            color: #fff;
            font-size: 26px;
            font-weight: 500;
        }

        .accordion p {
            font-size: 15px;
            margin: 0;
            padding: 5px 0;
        }

        .accordion-active .accordion-content {
            padding: 0 20px 20px;
            opacity: 1;
        }

        .accordion-active .accordion-header:after {
            content: "\2212";
        }

        .accordion-header:after {
            content: '\002B';
            color: #fff;
            font-weight: bold;
            float: right;
            margin-left: 5px;
        }
</style>
   </head>
   <body>
      <div class="accordion">
         <div class="accordion-header">
            <h4>Accordion title 1</h4>
         </div>
         <div class="accordion-content">
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellat maiores temporibus impedit consectetur id sint modi, quo sunt facere ipsum beatae? Natus quisquam iusto similique repudiandae adipisci in, voluptas maiores, molestiae blanditiis at consectetur cupiditate voluptates ducimus saepe cumque. Error nulla possimus a eligendi facere officiis soluta aliquam est quis molestias nam, officia adipisci, porro ut fugiat? Ipsam, odio fugiat!</p>
         </div>
      </div>
      <div class="accordion">
         <div class="accordion-header">
            <h4>Accordion title 2</h4>
         </div>
         <div class="accordion-content">
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellat maiores temporibus impedit consectetur id sint modi, quo sunt facere ipsum beatae? Natus quisquam iusto similique repudiandae adipisci in, voluptas maiores, molestiae blanditiis at consectetur cupiditate voluptates ducimus saepe cumque. Error nulla possimus a eligendi facere officiis soluta aliquam est quis molestias nam, officia adipisci, porro ut fugiat? Ipsam, odio fugiat!</p>
         </div>
      </div>
      <div class="accordion">
         <div class="accordion-header">
            <h4>Accordion title 3</h4>
         </div>
         <div class="accordion-content">
            <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Officia itaque harum explicabo beatae eos illum, amet reiciendis eaque expedita consectetur quo, velit magnam sunt doloribus dolore laudantium cum rem, fuga aut quidem ipsa libero quasi? Quasi ipsam unde ratione possimus illum alias, voluptas ullam soluta vel repudiandae perspiciatis. Nam at rerum eum excepturi? At facilis tempore temporibus consequatur in consequuntur voluptatum molestiae, vel a omnis, cum exercitationem ullam nemo ut!</p>
         </div>
      </div>
      <script>> 
        const accordions = document.querySelectorAll(".accordion");
const openAccordion = (accordion) => {
   const content = accordion.querySelector(".accordion-content");
   accordion.classList.add("accordion-active");
   content.style.maxHeight = content.scrollHeight + "px";
};
const closeAccordion = (accordion) => {
   const content = accordion.querySelector(".accordion-content");
   accordion.classList.remove("accordion-active");
   content.style.maxHeight = null;
};
accordions.forEach((accordion) => {
   const intro = accordion.querySelector(".accordion-header");
   const content = accordion.querySelector(".accordion-content");
   intro.onclick = () => {
      if (content.style.maxHeight) {
         closeAccordion(accordion);
      } else {
         accordions.forEach((accordion) => closeAccordion(accordion));
         openAccordion(accordion);
      }
   };
});
      </script> 
   </body>
</html>

Adding Animations

You can also enhance the experience by adding CSS animations or more advanced transitions like fading in/out. You can explore this by experimenting with opacity or height transitions.

6. Conclusion

By following this guide, you have built a simple yet effective collapsible accordion using HTML, CSS, and JavaScript. The accordion improves user experience by keeping content organized and interactive. You can easily extend and modify this design by adding more features, such as icons, animations, or dynamic content.

Now, you have a fully functional collapsible accordion, and you can apply it to any website that requires expandable/collapsible sections for better usability!