Skeleton
Placeholder shapes that hold space while content loads. The shimmer is pure CSS. The skeleton-to-content crossfade uses AnimatePresence with popLayout.
Live demo
Avatar
Text — 3 lines
Your recent activity has been summarised below.
3 tasks completed, 1 pending review.
Last updated just now.
Card
Alex Morgan
Product Designer · Active now
Why it animates
Content that loads asynchronously needs a placeholder that matches the shape of what's coming. A skeleton that mirrors the real layout reduces perceived shift and makes the wait feel intentional rather than broken.
Usage
import { Skeleton } from '@/components/ui/Skeleton'
<Skeleton shape="avatar" loading={isLoading}>
<img src={user.avatar} alt={user.name} className="w-10 h-10 rounded-full" />
</Skeleton>
<Skeleton shape="text" lines={3} loading={isLoading}>
<p>{content}</p>
</Skeleton>
<Skeleton shape="card" loading={isLoading}>
<UserCard user={user} />
</Skeleton>