Vercel Tabs

Crafting

npx shadcn add https://try.pungrumpy.com/r/vercel-tabs.json

A tabs component with animated indicators inspired by Vercel's design. Features smooth hover and active state transitions with dynamic indicator positioning.

How It Works

Unlike traditional tabs where indicators are static, this component uses two animated indicators that are positioned and sized dynamically relative to an inner container. The magic happens through a few techniques working together:

  1. Relative measurements — Each tab is measured against an inner container using getBoundingClientRect(). The measurement calculates the position relative to the inner container, returning left, top, width, and height for precise indicator positioning.

  2. useLayoutEffect synchronization — Measurements run synchronously before paint, preventing layout jumps when tabs change size. Both resize and scroll event listeners recalculate rects to keep indicators accurate on viewport changes and when the container scrolls horizontally.

  3. Dual indicators — The hover indicator animates left, top, width, and height to create a soft rounded highlight behind the hovered tab. It's hidden on mobile devices (hidden md:block) to reduce visual clutter on smaller screens. The active indicator is a bottom bar that animates left and width (with a subtle scaleX), clearly marking selection. Both use Motion's spring-like easing for a crisp, responsive feel.

  4. Overflow-friendly layout — The outer container is horizontally scrollable (overflow-x-auto) with shrink-0 tab items and touch-pan-x, so long tab sets remain usable on small screens without wrapping or jitter. The scroll listener ensures indicators stay aligned even when users scroll through tabs.

Built with motion.devmotion.dev for smooth, performant animations that adapt to each tab's dimensions automatically.

Was this helpful?