Skip to content

Instantly share code, notes, and snippets.

@ArcticLight
Last active August 29, 2015 14:20
Show Gist options
  • Save ArcticLight/7380b89c82442b9d679a to your computer and use it in GitHub Desktop.
Save ArcticLight/7380b89c82442b9d679a to your computer and use it in GitHub Desktop.
CSS Animations + Javascript = Hell
// This is a snippet that may or may not eventually make it live to my wobsite.
// This is the shortest code I currently know how to write that triggers my
// in/out animations correctly on toggle - every time - in the browser.
// The "Every Time" bit is the hardest bit.
function toggleReq() {
requirementsOpen = !requirementsOpen;
if(requirementsOpen) {
req.style.height=document.getElementById("reqcontent").offsetHeight+8+"px";
//prevents animations from stepping on each others' toes.
if(sync !== null) { window.clearTimeout(sync); }
//Timeout required, because otherwise the browser will do Odd Things
//like flash a 0px tall height, or animate in from the wrong height.
sync = window.setTimeout(function() {
//frob whether or not we even want animations, because of the above
//"Browser will do bad things otherwise" reason.
req.classList.toggle("anim", true);
//finally make it small.
req.style.height="1em";
//==================
//CSS ANIMATIONS WHY
//==================
//Apparently all of this toggling is ENTIRELY NECESSARY,
//without which the animation will Not Always Start(tm)
document.getElementById("plus").classList.toggle("spinOut", true);
document.getElementById("hbar").classList.toggle("minus", true);
document.getElementById("hbar").classList.toggle("minus", false);
document.getElementById("plus").classList.toggle("spinIn", false);
sync = null;
}, 50);
} else {
//prevent toe-stepping-on
if(sync !== null) { window.clearTimeout(sync); }
//turn on animations
req.classList.toggle("anim", true);
//prep the spin animation
document.getElementById("plus").classList.toggle("spinOut", false);
document.getElementById("hbar").classList.toggle("minus", false);
//do the spin animation in a timeout, otherwise it (apparently) will
//not always frob correctly.
sync = window.setTimeout(function() {
document.getElementById("hbar").classList.toggle("minus", true);
document.getElementById("plus").classList.toggle("spinIn", true);
//In order to make the browser animate opening the div to the full
//content height, we must SPECIFY the full content height. Stating "auto"
//instead will cause the browser to animate the div to 0px and then suddenly
//snap to full height for who-knows-what-reason.
req.style.height=document.getElementById("reqcontent").offsetHeight+8+"px";
//in order to let the text reflow when the browser window is resized, we actually
//*DO* want the req-div's style to say height:auto. Unfortunately, as stated above,
//if we set it to auto it will animate like it has Palsy.
//The solution is yet ANOTHER setTimeout.
//
// "Let's Nest Even More Callbacks!" (dot-tumblr-dot-com)
sync = window.setTimeout(function() {
req.classList.toggle("anim", false);
req.style.height="auto";
sync = null;
}, 500);
}, 50);
}
}
@hawkw
Copy link

hawkw commented May 5, 2015

I am terribly sorry you had to endure this thing but your rage is super great – it brings to mind the classic "Why PSD is Not My Favorite File Format".

@hawkw
Copy link

hawkw commented May 5, 2015

also, Is This Literate Programming? (yes)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment