---
title: 'Directional slide'
excerpt: 'Content slides with navigation direction; compose a traveling underline for the active tab.'
icon: 'MousePointer2'
---

## The primitive

A **directional slide** enters from the side that matches navigation — forward from the right, back from the left — so the panel feels like it came from where you were going. Sign of `next - prev` chooses `xPercent` (positive vs negative). Skip when `dir === 0` (first paint) so the initial view does not slide in from nowhere.

This is **not** a shared element: the panel remounts or rewrites content; only the motion direction carries continuity. Contrast with a traveling underline, which is one persistent node.

Click 1 → 2 → 3 and reverse: notice the entrance side flips with direction.

<ComponentPreview>
  <GsapDirectionalSlidePrimitive />

  <DocsFileTabs title="Directional slide">

```tsx title="directional-slide.tsx"
const dir = Math.sign(next - prev); // 1 forward, -1 back
if (dir === 0) return; // skip first paint
gsap.fromTo(
  '.gsap-dir-panel',
  { xPercent: dir * 8, autoAlpha: 0 },
  { xPercent: 0, autoAlpha: 1, duration: 0.22, ease: 'power2.out' }
);
```

```html title="directional-slide-markup.html"
<button>1</button>
<button>2</button>
<button>3</button>
<div class="gsap-dir-panel">Panel content</div>
```

  </DocsFileTabs>
</ComponentPreview>

## Use case — tabs + underline

Compose two primitives: a **shared element** underline (`x` + `scaleX` on one persistent bar) plus a **directional slide** on the panel. Do not conditional-render the underline — remounting snaps it. Keep `overwrite: 'auto'` on the indicator so rapid tab changes retarget cleanly.

Switch tabs: the underline travels; the panel slides in from the direction of travel.

<ComponentPreview>
  <GsapDirectionalSlideTabs />

  <DocsFileTabs title="Tabs with directional slide">

```tsx title="direction-tabs.tsx"
// underline — shared element
gsap.to('.gsap-indicator', {
  x: target.offsetLeft,
  scaleX: target.offsetWidth / baseWidth,
  duration: 0.28,
  ease: 'power2.inOut',
  transformOrigin: 'left center',
  overwrite: 'auto',
});

// panel — directional slide
const dir = Math.sign(next - prev);
gsap.fromTo(
  '.gsap-dir-panel',
  { xPercent: dir * 8, autoAlpha: 0 },
  { xPercent: 0, autoAlpha: 1, duration: 0.22, ease: 'power2.out' }
);
```

```html title="direction-tabs-markup.html"
<div class="relative flex gap-4 border-b">
  <span class="gsap-indicator absolute bottom-0 left-0 h-0.5 bg-foreground"></span>
  <button class="gsap-indicator-target">Overview</button>
  <button class="gsap-indicator-target">Analytics</button>
  <button class="gsap-indicator-target">Billing</button>
</div>
<div class="gsap-dir-panel">…</div>
```

  </DocsFileTabs>
</ComponentPreview>

See [Shared element](/learn/gsap-react/ui-patterns/shared-element) for the indicator alone.
