The taste framework
Animation is seasoning, not the meal. Three rules I follow on every site:
- Transform and opacity only. Never animate
top,left,width,height— they trigger layout on every frame. - One entrance pattern per section. A
y: 20 → 0fade-up withstagger: 0.1reads as craft; five different entrances read as chaos. - Honor
prefers-reduced-motion. Non-negotiable.
Scoped, cleaned-up GSAP in React
useGSAP(() => {
gsap.fromTo(".card",
{ y: 20, opacity: 0 },
{
scrollTrigger: { trigger: containerRef.current, start: "top 85%" },
y: 0, opacity: 1, duration: 0.6, stagger: 0.1, ease: "back.out(1.5)",
}
);
}, { scope: containerRef });
scope gives you selector scoping and automatic cleanup — no leaked ScrollTriggers on route changes.
Eases that feel human
| Ease | Feels like |
|---|---|
power3.out |
confident arrival |
back.out(1.5) |
playful pop |
elastic.out(1, 0.5) |
use once per site, max |
The elastic bounce is a spice jar, not a sauce bottle.