DEV Community

Cover image for Build a Beautiful Animated Accordion with Just HTML, CSS & JS , No Libraries Needed!
Sohrab zia
Sohrab zia

Posted on

Build a Beautiful Animated Accordion with Just HTML, CSS & JS , No Libraries Needed!

Ever wanted to create a gorgeous accordion UI that feels premium without using heavy frameworks or libraries? Let's build one from scratch that’s responsive, elegant, and buttery smooth.

DEMO

See the Pen Fun & Funky School Notebook Accordion | Bounce Animation + Handwritten Style by Sohrab zia (@sohrabzia) on CodePen.

🧠 What We'll Cover

βœ… Clean HTML structure
βœ… CSS animations and transitions
βœ… JavaScript for interaction
βœ… Advanced UI touches like hover states, shadows, and responsive tweaks
βœ… Bonus: Custom clip-path and handwriting-style content area

πŸ”§ The HTML Structure

We start with a simple, semantic layout:

<div class="accordion-container">
  <div class="accordion-item">
    <button class="accordion-header">
      Accordion Title 1
      <i class="fa-solid fa-chevron-down icon"></i>
    </button>
    <div class="accordion-content">
      <div class="accordion-body">
        <p>This is the content for the first accordion.</p>
      </div> 
    </div>
  </div>
  <!-- Add more items as needed -->
</div>
Enter fullscreen mode Exit fullscreen mode

🎨 The CSS Magic

We give this accordion some real flair β€” a mix of shadows, gradients, animations, and subtle hover effects:

Key Highlights:

  • Smooth max-height transitions
  • clip-path for a ribbon effect
  • @keyframes for a "slide-up" bounce feel
  • Handwritten font + paper-style lines for a whimsical twist
:root {
  --accordion-duration: 0.3s;
  --icon-rotate-open: 180deg;
}

/* Accordion Header */
.accordion-header {
  background: #f7d794;
  border-radius: 10px;
  padding: 15px 20px;
  font-weight: bold;
  cursor: pointer;
  transition: background var(--accordion-duration);
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
  position: relative;
}

/* Decorative Ribbon */
.accordion-header:before {
  content: "";
  position: absolute;
  top: -14px;
  right: 17px;
  width: 91px;
  height: 15px;
  background-color: #f7d794;
  clip-path: polygon(5% 0%, 95% 0%, 100% 100%, 0% 100%);
  transition: all 0.3s ease;
}

Enter fullscreen mode Exit fullscreen mode

πŸš€ The JavaScript That Powers It

Here's the JS logic that adds the open/close functionality and ensures only one accordion stays open:

document.addEventListener("DOMContentLoaded", () => {
  const headers = document.querySelectorAll(".accordion-header");

  headers.forEach((header) => {
    header.addEventListener("click", () => {
      const openHeader = document.querySelector(".accordion-header.active");
      const content = header.nextElementSibling;

      if (openHeader && openHeader !== header) {
        openHeader.classList.remove("active");
        openHeader.nextElementSibling.style.maxHeight = null;
      }

      const isActive = header.classList.contains("active");
      header.classList.toggle("active", !isActive);
      content.style.maxHeight = !isActive ? content.scrollHeight + "px" : null;
    });
  });
});

Enter fullscreen mode Exit fullscreen mode

πŸ“± Responsive Design Ready

@media (max-width: 600px) {
  .accordion-header {
    font-size: 15px;
    padding: 12px 16px;
  }

  .accordion-content {
    padding: 0 16px;
  }
}

Enter fullscreen mode Exit fullscreen mode

πŸ’‘ Pro Tips

Swap out the font with Google Fonts like 'Patrick Hand' for playful aesthetics.
Adjust the animation timing/distance to match your brand feel.
Replace icons with SVGs if you want more control.

🎁 Bonus: Style Variants You Can Add

Dark mode: Easily tweak with a few color variables.
FAQ style: Pre-load the first item open with a class.
Accordion inside cards: Wrap with .card for extra flair

Bonus Accordion

Top comments (0)