Creating a functional animated accordion with varying heights: a comprehensive guide

I've been working on creating an animated accordion feature that includes a series of clickable headings. When each heading is clicked, it should toggle to reveal or collapse a content panel underneath. The animation involves transitioning the height and opacity properties of each content panel using CSS. Everything works perfectly when I set a fixed pixel height for the expanded content panels, but my goal is to have flexible heights for them to accommodate varying content lengths.

Here's the code snippet from my current progress. I've defined a CSS class called display_on for revealing the content panel and utilized calc() to dynamically calculate the height property in pixels. While the animation behaves as expected for opacity adjustments, I'm facing challenges with the transition effect on the height property. It seems ineffective during expansion and leads to a sudden collapse instead of the smooth movement I desire during the collapse phase. Is there any way to achieve the desired functionality?

You can view a demo of my codepen implementation here: http://codepen.io/artocignus/pen/QGdPWx

Here's the HTML structure:

<h1 class="accordion_heading">
  Accordion Heading 1
</h1>
<div class="accordion_panel">
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...

// Repeat for other accordion items

Related CSS styling:

.accordion_heading{
  margin: 5px;
  font-size: 30px;
  color: #blue;
  background-color: grey;
  padding: 0 1em;
  width: 400px;
  border-radius: 5px;
}

// Define more CSS rules ...

.display_on{
  height: calc(100%);
  opacity: 1;
  transition: all 1s ease;
}

JavaScript function for toggling the display_on CSS class:

function accordionToggle(e){
  var target = e.target;
  if(target.classList.contains('accordion_heading')){
    var to_toggle = target.nextElementSibling;
        to_toggle.classList.toggle('display_on');
  }
}

document.addEventListener('click', accordionToggle);

Answer №1

Replace the height animation with max-height to allow for animated adjustments based on the element's height.

function toggleAccordion(e){
          var target = e.target;
          if(target.classList.contains('accordion_heading')){
            var toToggle = target.nextElementSibling;
            toToggle.classList.toggle('display_on');
          }
        }

        document.addEventListener('click', toggleAccordion);
.accordion_heading{
          margin: 5px;
          font-size: 30px;
          color: #blue;
          background-color: grey;
          padding: 0 1em;
          width: 400px;
          border-radius: 5px;
        }

        .accordion_heading:hover{
          cursor: pointer;
          color: crimson;
          transition: color 0.3s ease;
        }

        .accordion_panel{
          margin: 5px;
          width: 400px;
          opacity: 0;
          max-height: 0;
          transition: all 1s ease-out;
          overflow: hidden;
        }

        .display_on{
          opacity: 1;
          max-height: 500px;
          transition: all 1s ease-in;
        }
<h1 class="accordion_heading">
          Accordion Heading 1
        </h1>
        <div class="accordion_panel">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.
        </div>
        <h1 class="accordion_heading">
          Accordion Heading 2
        </h1>
        <div class="accordion_panel">
          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.
        </div>
        <h1 class="accordion_heading">
          Accordion Heading 3
        </h1>
        <div class="accordion_panel">
          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.
        </div>
        

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Setting a div's background using JavaScript works flawlessly on jsfiddle.net, but encounters issues when implemented in actual code

contains the files you need. For reference, here is the link to the code on I have attempted to remove all unnecessary elements from the actual project, but it has not made a difference. document.getElementById("image").style.backgroundImage = "url(" + d ...

Why is it that filling a DataTable with a variable doesn't work, but when I input the same value into a PHP site and request it using AJAX, it suddenly works?

Contained within the variable named "test" is the following data: {"data":[{"HistChar_ID":"4","Vorname":"Garnier","Nachname":"de Naplouse"},{"HistChar_ID":"2"," ...

Troubleshooting: Issue with Vue.js scroll to element functionality

While using v-for in my code, I encountered an issue where I am trying to scroll to a newly added comment but keep receiving this error message in the console: Cannot read property 'top' of undefined The error seems to be originating from this ...

Is there a way to adjust the alignment of the placeholder text to the top of a sizable input field?

Here is how my code currently appears: https://i.sstatic.net/WwXd2.png I am trying to align the text at the top of the input text field. I have attempted using align-text-top, align-top, and creating a custom class with vertical-align: top; and vertical ...

Having trouble with Window.open on Mobile Devices and Canvas?

I've created a unique "button" within the div element. This button is designed to detect user interaction, such as clicks or taps, and when triggered, it should open a new window with the URL: "http://www.google.com". However, while this functionality ...

Ways to determine if a string or HTML contains repeated consecutive elements

Assume I am working with the following string <div id="ch">abcdefg<img /><img />hij</div> <div id="ad">abc<img />defg<img />hij</div> strHtml = $('div#ch').html(); strHtmlFalse = $('div#ad&ap ...

The malfunction of the selenium emulation feature in the node environment

Issue I am trying to implement mobile emulation in Chrome using Selenium with Express. However, despite setting the capabilities for mobile emulation with an Apple iPhone 6 device, Chrome does not open in emulation mode and no errors are displayed. c ...

Solving the jQuery Context Menu Issue

I created this JQuery script to dynamically modify links generated on my Page (using Ruby on Rails will_paginate) into GET requests that fetch JSON data and update elements on my page. It works perfectly when the links are left-clicked. However, if a right ...

Unable to submit value on Ajax-powered dynamic select form

I need help with a dynamic Select element inside a form that is not submitting its value. Here is the code snippet: <table> <form> <tr> <td><select>(options values)</select></td> <td id='fill'>< ...

A template literal will not recognize an imported function

import {createTasks} from './app.js'; document.addEventListener("DOMContentLoaded", function () { function showNewTaskModal () { newTaskModal.classList.add('show'); const html = ` <d ...

Is there a way to divide text in one column and move it to another column on mobile and tablet devices?

Struggling with my bootstrap3 layout, I am attempting to shift content from one column to another on mobile and tablet screens. This adjustment is necessary so that the content appears under a specific heading or image in the adjacent column for optimal mo ...

I am looking to switch the content between two divs. Specifically, I want to take the content from div 1 and move it to div 2, while moving the

I am facing a challenge involving three divs. One of them is the main div, while the other two are positioned below it and contain different content. I am trying to find a way to swap the content between div one and div two in such a way that the original ...

The template seems to be holding out for the Observable to produce a single yield

Upon obtaining an array through a service, the template is used to create a list using *ngFor. The initial list functions correctly, however, there is a second list that utilizes a subset of the array and results in the following error: ERROR TypeError ...

Joomla website experiencing issues with Bootstrap popover functionality

Just wanted to share that I am currently working on this page: I found an example that inspired me from here: I have a feeling that Joomla might be including a resource that is causing conflicts with the popover not showing. This is the code snippet I h ...

Utilizing the power of JavaScript in an HTML file to develop a straightforward price calculator

I am new to the world of HTML coding and currently working on an assignment for my online computer course. I reached out to my professor for help, but unfortunately, he hasn't been very responsive. The task at hand is to create a basic cost calculator ...

The tooltips in the WordPress-Gulp-Starter-Kit running on Bootstrap 5 do not seem to be functioning properly

I'm having trouble with tooltips not working properly. The codebase I'm using is from this repository https://github.com/oguilleux/webpack-gulp-wordpress-starter-theme If you need more details, feel free to reach out. Here is my main.js file: ...

Immediately refresh the page after successfully loading the DOM through JavaScript

function selectDate(){ var d=document.getElementById("selecter").value; alert(d); var days=['Monday','Tuesday', 'Wednesday','Thursday', 'Friday', 'Saturday', 'Sunday']; / ...

What is the best way to iterate through multiple iframes?

I need help figuring out how to load one iframe while having the next one in line to be displayed. Is there a way to create a script that cycles through multiple iframes after a certain amount of time? ...

Guide to using AJAX for the GraphHopper Matrix API

I am struggling to send this JSON with the required information because I keep encountering an error during the request. message: "Unsupported content type application/x-www-form-urlencoded; charset=UTF-8" status: "finished" I'm not sure what I&apos ...

Is it possible to display images in PHP when the value matches the specified string?

Is there a faster and more efficient way to display one or multiple images if $value == $string? For instance, let's say I have a cell containing the string 'r o g'. If a user inputs ro, it should output <img src="red.gif"> and <im ...