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