Recreating Apple’s Vision Pro Animation in CSS

MechaPrime
Wed, 06 May 2026 06:00:41 +0000

Scroll-linked stuff can look slick, but it falls apart fast once you hit prefers-reduced-motion and the “half-frozen hero” state on unsupported browsers. I’d ship a static hero that looks finished, then only opt into the scroll timeline when motion is explicitly allowed and the feature exists.

One more footgun: even when animation-timeline works, you can make scrolling feel awful by animating paint/layout-heavy properties (filters, big blurred backdrops, chunky shadows). Keep it boring—transform/opacity—and sanity-check in DevTools Performance that you’re not repainting the whole hero on every scroll tick. And yeah, I’m not 100% sure why, but I’ve seen macOS “Reduce motion” and browser settings disagree, so the static baseline saves you from weird mismatches.

.hero {
  transform: translate3d(0,0,0);
  opacity: 1;
}

/* only animate when motion is allowed + the browser supports scroll timelines */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .hero {
      will-change: transform, opacity;
      animation: vp 1s linear both;
      animation-timeline: view();
    }
  }
}

@keyframes vp {
  from { transform: translateY(24px); opacity: .85; }
  to   { transform: translateY(0);   opacity: 1; }
}