Let's make an accordion which uses CSS for it's animations! Demo on Github here (or embedded below).
The markup for the accordion uses a definition list, with anchor links as the triggers.
<dl class="accordion">
<dt class="accordion-trigger"><a href="#" title="show more">Some content</a></dt>
<dd class="accordion-content">Lorem ipsum dolor ...</dd>
<dt class="accordion-trigger"><a href="#" title="show more">Some content</a></dt>
<dd class="accordion-content">Lorem ipsum dolor ...</dd>
<dt class="accordion-trigger"><a href="#" title="show more">Some content</a></dt>
<dd class="accordion-content">Lorem ipsum dolor ...</dd>
<dt class="accordion-trigger"><a href="#" title="show more">Some content</a></dt>
<dd class="accordion-content">Lorem ipsum dolor ...</dd>
</dl>
The CSS relating to the accordion content animation is fairly simple. Since height and display can't be animated with CSS, max-height is the key to sliding up and down. Initially, the max-height is set to 0 to hide the content; the vertical padding is also set to 0 otherwise the padding will still be visible. Overflow needs to be hidden otherwise any child elements of the content still take up room on the page and may overlap other elements. The opacity isn't required, but adds a nice effect to the animation.
After clicking on the trigger, the content-open
class is added to the appropriate accordion content element, and the max-height, opacity and padding are set. The transition declaration animates these properties to create the accordion animation.
.accordion-content {
/* css animation */
overflow: hidden;
padding: 0 1em;
max-height: 0;
opacity: 0;
/* add browser prefixes */
transition: all 0.3s ease;
}
.content-open {
max-height: 500px;
opacity: 1;
padding: 15px 20px;
}
The final part is the Javascript: this simply toggles classes on the relevant parts of the accordion.
$('.accordion-trigger a').on('click', function(e) {
e.preventDefault();
// cache the link so you don't have to keep getting a jQuery object
var triggerDOM = $(this);
if(triggerDOM.hasClass('closed')) {
// find the associated accordion content and add the open class to it to trigger the animation
triggerDOM.closest('.accordion-trigger').next('.accordion-content').addClass('content-open');
// update the trigger
triggerDOM.removeClass('closed').addClass('open');
} else if(triggerDOM.hasClass('open')) {
// if the accordion is already open, then close it
triggerDOM.removeClass('open').addClass('closed');
// remove class from content to trigger close animation
triggerDOM.closest('.accordion-trigger').next('.accordion-content').removeClass('content-open');
}
});