DEV Community

Cover image for Creating an Accordion using vanilla Javascript
AkshayKhot07
AkshayKhot07

Posted on

Creating an Accordion using vanilla Javascript

Let's create a Facts Accordion using HTML, CSS and Vanilla Javascript

Firstly we will create an HTML skeleton of the accordion. There will be 4 Facts card. So the HTML will look like the below :

    <div class="container">
      <h2 class="accordion-title">Facts About Mars!</h2>
      <div class="faq-container grid">

        <div class="faq-item">
          <header class="faq-header">
            <i class="ri-add-line"></i>
            <h4 class="faq-header-title">Also known as the Red Planet</h4>
          </header>
          <div class="faq-desp">
            <p class="faq-desp-content">
              This is because Mars is covered in soil, rock, and dust made from
              iron oxide which gives the surface a red rusty colour
            </p>
          </div>
        </div>

     </div>
    </div>

Enter fullscreen mode Exit fullscreen mode

There will be 3 more facts card [div with a class of faq-item] inside the [div with a class of faq-container]. We will use CSS grid to structure the facts cards:
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}

Our goal is to show/hide the Facts card description [div tag with a class of faq-desp] by clicking on the card header [header tag with a class of faq-header]

Firstly we will hide the Facts card description using the CSS property height: 0px and overflow: hidden like below:
.faq-desp {
overflow: hidden;
height: 0px;
}

Now the exciting part is to toggle (show/hide) the description using Javascript. Code snippet below:

const faqItems = document.querySelectorAll(".faq-item");

faqItems.forEach((faq) => {
  const faqHeader = faq.querySelector(".faq-header");

  faqHeader.addEventListener("click", () => {
    const openFaq = document.querySelector(".faq-open");

    toogleFaq(faq);

    if (openFaq && openFaq !== faq) {
      toogleFaq(openFaq);
    }
  });
});

const toogleFaq = (faq) => {
  const faqDescription = faq.querySelector(".faq-desp");

  if (faq.classList.contains("faq-open")) {
    faqDescription.removeAttribute("style");
    faq.classList.remove("faq-open");
  } else {
    faqDescription.style.height = faqDescription.scrollHeight + "px";
    faq.classList.add("faq-open");
  }
};
Enter fullscreen mode Exit fullscreen mode

Steps to achieve the goal:

  1. Select all Facts cards using querySelectorAll
  2. Loop over each card using forEach and select the card header
  3. Add a click event listener on the header and call the toggle function (it shows/hide the fact card description) with the card as an argument in the callback function of the event listener
  4. The toggle function selects the card description and adds an inline style of height which is equal to the scrollHeight. [The scrollHeight property returns the height of an element including padding, but excluding borders, scrollbars, or margins]
  5. We have achieved our goal. Rest I have added additional styles to make the accordion look presentable

Please find the complete code in the codesandbox here: Code Sandbox

Top comments (0)