KKKim Kakiiza
All posts
FRONTEND · PERFORMANCEMay 12, 20262026

Motion Without a Framework

Rebuilding this portfolio with CSS-only motion — why I dropped the animation libraries and what the site got in return.

The previous version of this site shipped a 3D hero, a scroll-reveal library, and a motion engine. It looked alive. It also asked every visitor to download a small framework before the first screen settled. For the redesign I set a harder constraint: no animation dependencies at all. Everything moves with CSS.

The Constraint Did the Design Work

Removing the libraries was not a sacrifice — it was a brief. When the only tools are transitions, keyframes, and transforms, you stop reaching for spectacle and start reaching for restraint. The marquee is one @keyframes rule. The menu overlay is an opacity and visibility transition with a staggered translateY on its children. The card hovers are border-color shifts. None of it needs JavaScript to exist.

Where JavaScript Still Earns Its Place

A few things genuinely need the client:

  • The live New York clock — an interval and a mounted guard so the server and client agree on first paint.
  • The hero spotlight — a pointermove listener that writes two CSS custom properties, throttled through requestAnimationFrame.
  • The menu overlay state — a single boolean.

That is the whole budget. The spotlight does not animate in JavaScript; it just moves the origin of a CSS radial gradient. The browser does the rest.

const onMove = (e: PointerEvent) => {
  cancelAnimationFrame(raf);
  raf = requestAnimationFrame(() => {
    el.style.setProperty("--mx", `${e.clientX - rect.left}px`);
    el.style.setProperty("--my", `${e.clientY - rect.top}px`);
  });
};

Reduced Motion Is the Real Test

Every motion in the site has an off switch. prefers-reduced-motion collapses transition and animation durations to nearly zero, the marquee stops, smooth scrolling becomes instant, and the spotlight listener never attaches. If a motion cannot be turned off cleanly, it should not be there.

What the Site Got Back

First-load JavaScript dropped to almost nothing. The page is mostly server-rendered HTML and CSS. It still feels considered — the type still scales, the overlay still sweeps in — but the visitor does not pay a framework tax for it. Interactivity is cheapest when it is honest about how little it actually needs.