2

I'm trying to code an animated accordion consisting of a series of clickable headings which, when clicked, will toggle between revealing or collapsing a content panel underneath each heading. The animation simply consists of a CSS transition on the height and opacity properties of the content panels. It all works as expected if I specify a fixed height in pixels for the expanded content panel, but in my case I want each expanded content panel to have flexible height in order to fit variable content.

Below is the code of my best effort so far. My CSS class for revealing the content panel is display_on, and I'm using calc() to return a pixel value for the height property. The animation works as expected for opacity, but I'm stumped with its behaviour on the height property. It seems to have no effect on the reveal phase, and in the collapse phase it simply causes a delay equal to the transition time (1 second) followed by a sharp collapse of the content panel, as opposed to the gradual movement I'm looking for. Is there any way to make this work in the way that I want?

Here's a link to my codepen demo: http://codepen.io/artocignus/pen/QGdPWx

My HTML markup:

<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>

My CSS:

.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;
  height: 0;
  opacity: 0;
  overflow: hidden;
  transition: all 1s ease;
}

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

My JavaScript to toggle 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);
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
artocignus
  • 41
  • 3
  • Solution: http://stackoverflow.com/questions/3508605/how-can-i-transition-height-0-to-height-auto-using-css See demo: https://jsfiddle.net/0dn1sgo8/1/ – sinisake Nov 20 '16 at 17:29
  • This works great! If I may nitpick though, the transition doesn't have the same speed in both directions, because when collapsing, it is calculated over the actual height, but when expanding, it is calculated over the max-height value, which is set very high on purpose. Is this the only way to make it work? – artocignus Nov 20 '16 at 17:47
  • Not sure, there are some things that can be done, with js: https://davidwalsh.name/css-slide (author pointed exactly what you have said, too), but, rather than 'injecting styles' with js - i would use javascript/jquery instead css transitions, in that case... – sinisake Nov 20 '16 at 17:56

1 Answers1

0

Use max-height in place of height animation to animate it according to ur height

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);
.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>
jafarbtech
  • 6,842
  • 1
  • 36
  • 55