Back to Dictionary
Page & View Transitions
●○○Ready to Use
Recommended default

Slide Transition

A view or component enters the screen by sliding linearly from an edge, providing spatial context about where the user is navigating to.

Use

Mobile app screen navigation (pushing a new view)

Avoid

Flipping between unrelated top-level tabs (use Fade instead)

Safer Alternative

No safer default listed.

Risk Level

Low risk

Live Demo

List
Map

What It Is

A view or component enters the screen by sliding linearly from an edge, providing spatial context about where the user is navigating to.

When to Use

  • Mobile app screen navigation (pushing a new view)
  • Carousels and image galleries
  • Wizard steps in a form

When NOT to Use

  • Flipping between unrelated top-level tabs (use Fade instead)
  • Replacing small inline text

Configuration Tips

  • 01Couple the slide with a subtle fade-in (opacity 0 to 1) to soften the edge
  • 02Use a slightly bouncy spring to make the slide feel physical

You've Seen It In

iOS NavigationInstagramTypeform

AI Implementation Prompts

Move from a fast scaffold to production details, then tune timing and edge states.

Transition between these two steps by sliding out to the left and sliding in from the right.

Reference Implementation

The same implementation approach used by the live preview, kept compact enough to inspect and adapt.

'use client';
import { motion, AnimatePresence } from 'framer-motion';
import { useState, useEffect } from 'react';

export function SlideTransitionDemo({ isPlaying = false }: { isPlaying?: boolean }) {
    const [tab, setTab] = useState(0);

    useEffect(() => {
        if (!isPlaying) {
            setTab(0);
            return;
        }
        const interval = setInterval(() => {
            setTab((prev) => (prev === 0 ? 1 : 0));
        }, 2000);
        return () => clearInterval(interval);
    }, [isPlaying]);

    return (
        <div className="flex h-64 w-full flex-col items-center justify-center overflow-hidden rounded-2xl bg-white p-6 shadow-sm ring-1 ring-stone-200">

            {"text-stone-400 italic">/* Tab Header */}
            <div className="mb-4 flex gap-2 rounded-full bg-stone-100 p-1.5 ring-1 ring-stone-200/50">
                <div className={`flex min-w-[100px] items-center justify-center rounded-full px-6 py-2 text-sm font-medium transition-colors ${tab === 0 ? 'bg-white text-stone-900 shadow-sm' : 'text-stone-500'}`}>List</div>
                <div className={`flex min-w-[100px] items-center justify-center rounded-full px-6 py-2 text-sm font-medium transition-colors ${tab === 1 ? 'bg-white text-stone-900 shadow-sm' : 'text-stone-500'}`}>Map</div>
            </div>

            <div className="relative h-48 w-full max-w-[320px] overflow-hidden rounded-xl bg-white shadow-sm ring-1 ring-stone-200">
                <AnimatePresence mode="popLayout" initial={false}>
                    <motion.div
                        key={tab}
                        initial={{ x: tab === 1 ? 320 : -320, opacity: 0 }}
                        animate={{ x: 0, opacity: 1 }}
                        exit={{ x: tab === 1 ? -320 : 320, opacity: 0 }}
                        transition={{ type: 'spring', stiffness: 300, damping: 25 }}
                        className="absolute inset-0 flex flex-col p-6"
                    >
                        {tab === 0 ? (
                            <div className="flex flex-col gap-4">
                                <div className="h-4 w-full rounded bg-stone-200" />
                                <div className="h-4 w-3/4 rounded bg-stone-200" />
                                <div className="h-4 w-5/6 rounded bg-stone-200" />
                                <div className="h-4 w-1/2 rounded bg-stone-200" />
                            </div>
                        ) : (
                            <div className="flex h-full w-full items-center justify-center rounded-lg bg-stone-200">
                                <div className="h-10 w-10 rounded-full bg-stone-400" />
                            </div>
                        )}
                    </motion.div>
                </AnimatePresence>
            </div>
        </div>
    );
}