Menü schliessen
Created: December 30th 2024
Last updated: December 30th 2024
Categories: CSS,  IT Development,  JavaScript Development,  Php,  Wordpress
Author: Nikola Jevtic

Creating Smooth, Dynamic Accordions in JavaScript: A Step-by-Step Guide

Donation Section: Background
Monero Badge: QR-Code
Monero Badge: Logo Icon Donate with Monero Badge: Logo Text
82uymVXLkvVbB4c4JpTd1tYm1yj1cKPKR2wqmw3XF8YXKTmY7JrTriP4pVwp2EJYBnCFdXhLq4zfFA6ic7VAWCFX5wfQbCC

JavaScript accordions are a staple of modern web interfaces, providing an elegant way to display content in a compact and organized manner. Whether you’re a beginner developer or an experienced tech enthusiast, creating smooth and dynamic accordions is a valuable skill to enhance your projects.

In this tutorial, we’ll walk you through building a generalized JavaScript accordion with smooth animations, explaining its benefits, dependencies, and potential use cases. By the end, you’ll have a reusable solution ready for integration into any web project.


What Is an Accordion?

An accordion is a UI component that organizes content into expandable and collapsible sections. It’s commonly used in FAQs, navigation menus, and dashboards. Accordions save space and improve the user experience by presenting content dynamically.


Use Cases for JavaScript Accordions

  • FAQs: Organize questions and answers dynamically.
  • Navigation Menus: Create collapsible menus for compact design.
  • Dashboards: Show or hide additional details for individual items.
  • Content Management: Allow users to manage expandable content sections efficiently.

Dependencies and Prerequisites

To create this accordion, you’ll need:

  • Basic HTML and CSS: A basic understanding of HTML structure and CSS styling.
  • JavaScript: Familiarity with JavaScript for implementing logic and animations.
  • No Libraries Needed: This tutorial uses plain JavaScript for flexibility.

Ensure you’re using a modern browser for smooth animations and compatibility.


Step 1: HTML Structure

The HTML structure is simple and serves as the foundation of the accordion. Here’s the markup:

<div id="accordion-container">
    <div class="accordion">
        <div class="accordion-header">
            <h3>Accordion 1</h3>
        </div>
        <div class="accordion-body">
            <div class="accordion-content">
                <p>Content for accordion 1.</p>
                <p>Content for accordion 1.</p>
                <p>Content for accordion 1.</p>
            </div>
        </div>
    </div>
    <div class="accordion">
        <div class="accordion-header">
            <h3>Accordion 2</h3>
        </div>
        <div class="accordion-body">
            <div class="accordion-content">
                <p>Content for accordion 2.</p>
                <p>Content for accordion 2.</p>
                <p>Content for accordion 2.</p>
            </div>
        </div>
    </div>
</div>

Step 2: CSS for Styling

/* Basic styles for the accordion */
.accordion {
  border: 1px solid #ccc;
  margin: 10px 0;
}

.accordion-header {
  padding: 10px;
  background-color: #f7f7f7;
  cursor: pointer;
  user-select: none;
}

.accordion-body {
  overflow: hidden;
  display: none; /* Hidden by default */
  border-top: 1px solid #ccc;
}

.accordion-content {
  padding: 0 20px
}

Step 3: JavaScript Logic

Animation Utilities

These utility functions handle the smooth animations:

// Animation Utilities
function slideUp(target, duration = 300) {
  target.style.transitionProperty = 'height, margin, padding';
  target.style.transitionDuration = `${duration}ms`;
  target.style.boxSizing = 'border-box';
  target.style.height = `${target.offsetHeight}px`; // Set current height
  target.offsetHeight; // Force repaint
  target.style.overflow = 'hidden';
  target.style.height = 0;
  target.style.paddingTop = 0;
  target.style.paddingBottom = 0;
  target.style.marginTop = 0;
  target.style.marginBottom = 0;

  window.setTimeout(() => {
    target.style.display = 'none';
    target.style.removeProperty('height');
    target.style.removeProperty('padding-top');
    target.style.removeProperty('padding-bottom');
    target.style.removeProperty('margin-top');
    target.style.removeProperty('margin-bottom');
    target.style.removeProperty('overflow');
    target.style.removeProperty('transition-duration');
    target.style.removeProperty('transition-property');
  }, duration);
}

function slideDown(target, duration = 300) {
  target.style.removeProperty('display');
  let display = window.getComputedStyle(target).display;

  if (display === 'none') display = 'block';
  target.style.display = display;

  const height = target.offsetHeight;
  target.style.overflow = 'hidden';
  target.style.height = 0;
  target.style.paddingTop = 0;
  target.style.paddingBottom = 0;
  target.style.marginTop = 0;
  target.style.marginBottom = 0;
  target.offsetHeight; // Force repaint
  target.style.boxSizing = 'border-box';
  target.style.transitionProperty = 'height, margin, padding';
  target.style.transitionDuration = `${duration}ms`;
  target.style.height = `${height}px`;

  window.setTimeout(() => {
    target.style.removeProperty('height');
    target.style.removeProperty('overflow');
    target.style.removeProperty('transition-duration');
    target.style.removeProperty('transition-property');
  }, duration);
}

function slideToggle(target, duration = 300) {
  if (window.getComputedStyle(target).display === 'none') {
    return slideDown(target, duration);
  } else {
    return slideUp(target, duration);
  }
}

Accordion Initialization

function handleAccordions(selector) {
  const accordions = document.querySelectorAll(selector);

  accordions.forEach(accordion => {
    if (accordion.classList.contains('initialized')) return;

    const header = accordion.querySelector('.accordion-header');
    const body = accordion.querySelector('.accordion-body');

    if (body) body.style.display = 'none';

    header.addEventListener('click', () => {
      slideToggle(body, 300);
    });

    accordion.classList.add('initialized');
  });
}

document.addEventListener('DOMContentLoaded', function () {
  handleAccordions('.accordion');
});

Try It Out

You can see a working example of this accordion script in action on JSFiddle. Visit the link below to explore the code and test its functionality:

Explore the Accordion Example on JSFiddle