Skip to main content

Accordion with Vanilla JS: Full Code

Overview

This guide demonstrates how to build a responsive accordion component using purely Vanilla JavaScript, HTML, and CSS. An accordion allows users to toggle the visibility of content sections, efficiently managing screen space by displaying only the necessary information. We'll focus on a clean, maintainable structure and dynamic interaction without external libraries.

Implementation

Here is the complete code for the accordion, combining HTML, CSS, and JavaScript into a single, cohesive block.

LIVE PREVIEW
Interactive

An accordion is a graphical control element comprising a vertically stacked list of items such as labels or thumbnails. Each item can be "expanded" or "collapsed" to reveal or hide the content associated with that item.

Using Vanilla JavaScript provides maximum control, reduces dependency on external libraries, and often results in smaller bundle sizes and faster performance. It's excellent for understanding core web development concepts and building lightweight components.

The smooth open/close effect is achieved using CSS max-height and transition. When an item is collapsed, its max-height is set to 0 and overflow: hidden. When expanded, JavaScript sets max-height to the actual scrollHeight of its content, allowing CSS to animate the change.

  • max-height: 0; to hide.
  • max-height: content.scrollHeight + 'px'; to show.
  • transition: max-height 0.3s ease-out; for animation.
SOURCE CODE
<style>
  /* Basic Reset/Body Styling (optional, for demo context) */
  body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    margin: 0;
    padding: 20px;
    background-color: #f4f7f6;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    min-height: 100vh;
    box-sizing: border-box;
  }

  /* Accordion Container */
  .accordion {
    width: 100%;
    max-width: 600px;
    background-color: #ffffff;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  }

  /* Accordion Item */
  .accordion-item {
    border-bottom: 1px solid #f0f0f0;
  }

  .accordion-item:last-child {
    border-bottom: none;
  }

  /* Accordion Header (Button) */
  .accordion-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    padding: 15px 20px;
    background-color: #ffffff;
    color: #333;
    font-size: 1.1em;
    font-weight: 600;
    border: none;
    cursor: pointer;
    text-align: left;
    outline: none;
    transition: background-color 0.3s ease, color 0.3s ease;
  }

  .accordion-header:hover {
    background-color: #f9f9f9;
  }

  .accordion-header.active {
    background-color: #eef7f6;
    color: #1e88e5; /* Accent color when active */
  }

  /* Indicator Icon */
  .accordion-header::after {
    content: '\02795'; /* Plus sign */
    font-size: 0.9em;
    color: #888;
    transition: transform 0.3s ease, color 0.3s ease;
    margin-left: 10px;
  }

  .accordion-header.active::after {
    content: '\2796'; /* Minus sign */
    color: #1e88e5;
    transform: rotate(0deg); /* No rotation needed for minus */
  }

  /* Accordion Content */
  .accordion-content {
    background-color: #fefefe;
    max-height: 0; /* Initially hidden */
    overflow: hidden;
    transition: max-height 0.3s ease-out;
  }

  .accordion-content-inner {
    padding: 15px 20px;
    color: #555;
    line-height: 1.6;
  }

  .accordion-content-inner p:last-child,
  .accordion-content-inner ul:last-child {
    margin-bottom: 0;
  }

  .accordion-content-inner ul {
    margin-top: 10px;
    padding-left: 20px;
    list-style: disc;
  }
</style>

<div id="accordion" class="accordion">
  <div class="accordion-item">
    <button class="accordion-header">What is an Accordion?</button>
    <div class="accordion-content">
      <div class="accordion-content-inner">
        <p>An accordion is a graphical control element comprising a vertically stacked list of items such as labels or thumbnails. Each item can be "expanded" or "collapsed" to reveal or hide the content associated with that item.</p>
      </div>
    </div>
  </div>

  <div class="accordion-item">
    <button class="accordion-header">Why use Vanilla JS?</button>
    <div class="accordion-content">
      <div class="accordion-content-inner">
        <p>Using Vanilla JavaScript provides maximum control, reduces dependency on external libraries, and often results in smaller bundle sizes and faster performance. It's excellent for understanding core web development concepts and building lightweight components.</p>
      </div>
    </div>
  </div>

  <div class="accordion-item">
    <button class="accordion-header">How does the CSS transition work?</button>
    <div class="accordion-content">
      <div class="accordion-content-inner">
        <p>The smooth open/close effect is achieved using CSS <code>max-height</code> and <code>transition</code>. When an item is collapsed, its <code>max-height</code> is set to <code>0</code> and <code>overflow: hidden</code>. When expanded, JavaScript sets <code>max-height</code> to the actual <code>scrollHeight</code> of its content, allowing CSS to animate the change.</p>
        <ul>
          <li><code>max-height: 0;</code> to hide.</li>
          <li><code>max-height: content.scrollHeight + 'px';</code> to show.</li>
          <li><code>transition: max-height 0.3s ease-out;</code> for animation.</li>
        </ul>
      </div>
    </div>
  </div>
</div>

<script>
  document.addEventListener('DOMContentLoaded', () => {
    const accordionHeaders = document.querySelectorAll('.accordion-header');

    accordionHeaders.forEach(header => {
      header.addEventListener('click', () => {
        // Find the next sibling element, which is the accordion-content div
        const content = header.nextElementSibling;

        // Toggle the 'active' class on the header
        header.classList.toggle('active');

        // Toggle the max-height for the content
        if (header.classList.contains('active')) {
          // Set max-height to its scrollHeight to reveal content smoothly
          // We use scrollHeight to get the full height of the content, even if it's dynamic
          content.style.maxHeight = content.scrollHeight + 'px';
        } else {
          // Collapse content by setting max-height back to 0
          content.style.maxHeight = '0';
        }
      });
    });
  });
</script>

Final Thoughts

This Vanilla JS accordion provides a robust and efficient solution for interactive content display. By adhering to core web standards, it offers excellent performance, accessibility, and maintainability. This foundational structure can be easily extended with features like single-item expansion, keyboard navigation, or integration with dynamic data sources, making it a versatile component in any frontend toolkit.

โ„น️ Note: Code snippets are ready to copy-paste. Happy coding!

๐Ÿ“š More to Read

Comments

Popular posts from this blog

Top 5 Gradient Buttons CSS Styles

### CATEGORY: CSS Effects **TAGS**: gradient buttons, CSS styles, user interface, frontend development **SUMMARY**: Discover the top 5 gradient button styles using pure CSS. These styles enhance the visual appeal of your web applications with dynamic and appealing UI elements. --- ## Introduction Gradient buttons are a popular choice in modern web design to draw attention and improve user experience. They create a stunning visual effect by transitioning between two or more colors. In this article, we will explore 5 unique gradient button styles that you can implement using only CSS. ## 1. Neon Gradient Button **Description**: This style creates a vibrant neon effect with a glowing border around the button. ● LIVE PREVIEW Interactive ...

5 Creative Loading Spinners Designs

Introduction Loading spinners are more than just a visual cue; they're critical elements in user experience design. A well-crafted spinner can mitigate perceived wait times, reassure users that the system is active, and even delight them with subtle animations. As frontend developers and UI engineers, our goal is to integrate these seamlessly and efficiently. Here, we'll explore five distinct, creative loading spinner designs, each implemented with concise HTML and CSS, focusing on performance and visual appeal. 1. Orbiting Dots Loader This design features multiple small dots that gracefully orbit a central point, creating a fluid and engaging animation. It's a classic pattern made elegant through synchronized but offset movements. ● LIVE PREVIEW Interactive ...