Skip to content

Instantly share code, notes, and snippets.

@azinasili
Created January 7, 2019 11:11
Show Gist options
  • Save azinasili/0547005629cccd7349fbcbb22d9bc27f to your computer and use it in GitHub Desktop.
Save azinasili/0547005629cccd7349fbcbb22d9bc27f to your computer and use it in GitHub Desktop.
Functions to enable animating collapsible sections
// Element in to expand/collapse needs to have `overflow: hidden` applied to it
/**
* Collapse element height
* @param {HTMLElement} element - Element to collapse
* @param {Number} [height=0] - Size of element height in pixels
*/
function collapseSection(element, height = 0) {
const sectionHeight = element.scrollHeight;
const elementTransition = element.style.transition;
// temporarily disable all css transitions
element.style.transition = '';
// on the next frame (as soon as the previous style change has taken effect),
// explicitly set the element's height to its current pixel height, so we
// aren't transitioning out of 'auto'
requestAnimationFrame(() => {
element.style.height = `${sectionHeight}px`;
element.style.transition = elementTransition;
// on the next frame (as soon as the previous style change has taken effect),
// have the element transition to height: 0
requestAnimationFrame(() => {
element.style.height = `${height}px`;
});
});
element.setAttribute('data-collapsed', 'true');
}
/**
* Expand collapsed element
* @param {HTMLElement} element - Element to collapse
*/
function expandSection(element) {
const sectionHeight = element.scrollHeight;
element.style.height = `${sectionHeight}px`;
// When the next css transition finishes (which should be the one we just triggered)
// remove this event listener so it only gets triggered once
element.addEventListener('transitionend', function removeEvent() {
element.removeEventListener('transitionend', removeEvent);
element.style.height = null;
});
element.setAttribute('data-collapsed', 'false');
}
/**
* Toggle collapsing an element's height
* @param {HTMLElement} element - Element to collapse
* @param {Number} [height] - Size of element height in pixels
*/
function toggleCollapseSection(element, height) {
if (element.getAttribute('data-collapsed') === 'true') {
expandSection(element);
} else {
collapseSection(element, height);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment