Skip to content

Components

Skeleton Screens That Don't Lie — Match the Shape or Ship a Spinner

One Gradient Keyframe for the Shimmer, and the Rule That Decides Skeleton vs Spinner
Written by Aiden Wood Founder and Lead Design Engineer
💀 ✨ ⏳

Skeleton screens won the loading-state argument years ago: perceived performance improves when the page sketches its own layout instead of showing a spinner in a void. But there's a catch nobody mentions — a skeleton is a promise about layout, and a skeleton that promises three cards then renders a table has just caused the exact jarring swap it existed to prevent.

Velocity X's free loading-skeleton is the CSS half done right; the shape-matching half is a rule you have to keep.

The Money Pattern

The shimmer is one background gradient sliding across each grey block — no JS, no SVG, compositor-friendly:

.skeleton {
  background: linear-gradient(
    90deg,
    theme(colors.neutral.200) 25%,
    theme(colors.neutral.100) 50%,
    theme(colors.neutral.200) 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.6s linear infinite;
  border-radius: theme(borderRadius.md);
}

@keyframes shimmer {
  to { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; }
}

Compose blocks to mirror the real component: a circle for the avatar, a 60%-width bar for the title, two full-width bars for body text — with the same spacing utilities the real component uses, so loading and loaded are pixel-compatible. That's the whole discipline: the skeleton imports its dimensions from the design, never approximates them.

The Catch

Skeletons have a speed window. Under ~200ms, rendering one is churn — gate it so fast responses go straight to content. Past ~10 seconds, a skeleton becomes a lie of a different kind ("almost there!" forever) — long waits need progress or honesty, not shimmer.

And mark the region aria-busy="true" while loading. Without it a screen reader announces a page of nothing; with it, assistive tech knows to wait. Remove it when content lands — it's the cheapest correct loading semantics on the web.

The Verdict

Skeleton if you know the shape, spinner if you don't, nothing if it's fast. The shimmer is free and MIT — loading-skeleton, source in the public repo — and the app-shell variants (card grids, data grids) live in the full library.

Let us make some quick suggestions?

Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.