Note · · 3 min
The reveal that revealed nothing
A scroll animation that hid content instead of showing it, and passed every "it builds" check. The bug was one word. The lesson was about what "verified" has to mean.
Most sections on this site fade up as you scroll to them. During the rebuild, a whole run of them faded up to nothing and stayed blank. The animation was firing. The content was there. And the build was green. The bug was a single word.
The setup that caused it
To avoid a flash of unstyled content, I start animated elements hidden in CSS: while JavaScript is present, anything tagged to animate in begins at zero opacity. Then, on scroll, the animation library fades each one from invisible to visible. Clean idea. The reveal is supposed to carry the element from opacity: 0 up to opacity: 1.
The one word
I told the animation to play from a hidden state:
gsap.from(el, { opacity: 0 }) A "from" tween reads the element's current value as the destination and animates starting from the value you hand it. But the current value was already zero, set by my no-flash CSS. So the library dutifully animated the element from zero to zero. A perfectly executed fade, from invisible, to invisible. The fix was to state both ends explicitly instead of letting it infer the end from a starting point I had already forced to zero:
gsap.fromTo(el, { opacity: 0 }, { opacity: 1 }) Why a green build lied
Here is the part I actually keep. The build compiled. The page loaded. No error anywhere. Every automated signal said the work was done, because none of them scrolled the page and looked at whether the content was visible. "It builds" and "it works" are different claims, and the gap between them is exactly where this kind of bug lives.
I caught it by driving a real browser, scrolling to each section, and reading back the computed opacity of the elements that were supposed to have appeared. They read 0. That number, after a real scroll, is the only thing that would have told the truth.
The habit
When a change is visual or behavioral, the check has to exercise the behavior itself. For a reveal that means: scroll it, then assert the element is genuinely visible. A build that turns red on failure is worth a lot. A build that stays green while shipping a blank page is worth watching closely.