Skip to content

Loading skeleton

Source: kaleidoscope/src/demos/loading-skeleton.tsx Category: Animation

Loading skeleton — placeholder rectangles shaped like the content that’s loading. A shimmer animation signals “still working” without the jarring binary of “spinner → content”. Users perceive the page as loading faster than with a spinner even when the actual time is identical.

function Skeleton({ width = '100%', height = 14 }) {
return (
<div style={{ width, height, borderRadius: 4, overflow: 'hidden', position: 'relative', background: '#1e293b' }}>
<div className="shimmer" />
</div>
);
}
// CSS
.shimmer {
position: absolute; inset: 0;
width: 40%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.08), transparent);
animation: shimmer 1.6s linear infinite;
}
@keyframes shimmer { to { transform: translateX(350%); } }
  • Initial page loads where layout is predictable (card grid, list view)
  • Stream-in content (chat, comments) where the user can start reading shortly before all data arrives
  • Long-loading media (image grids, video thumbnails) where the final shape is known
  • Error states. If the load fails, skeletons keep shimmering forever. Timeout + retry UI.
  • Infinite variance in content shape. A chat with messages of wildly different lengths looks silly with uniform skeletons.
  • Very short loads (under 300ms). Skeletons flash in and out; just show the real content when it arrives.
  • Match the real layout. Skeleton and loaded content should occupy the same dimensions. Otherwise content shift happens when the load completes — worse than no skeleton.
  • Don’t animate too fast. Shimmer speed between 1.2-2s per cycle is comfortable. Faster feels anxious; slower feels stalled.
  • Respect prefers-reduced-motion. Render the gray shapes without shimmer; static skeleton is fine.
  • will-change: transform on the shimmer element helps GPU composition. Especially useful on mobile.
  • Keys on dynamic lists. If you render N skeletons and then N real items, use stable keys so React reconciles correctly and transitions don’t flash.
  • Terminal version. Ink version uses ░▒ block characters in a wave pattern. No opacity, no transforms — just re-render characters per frame. See kaleidoscope source.