Skeleton

A loading placeholder that mimics the shape of content while data is being fetched. Use it in place of actual content to reduce perceived loading time and layout shift.

  • CSS-only pulse animation using animate-pulse
  • Uses bg-muted token — adapts to light/dark mode
  • Composable — size and shape via className
  • No JS, no dependencies

import { Skeleton }from "@aetherstack/ui"

skeleton.tsx
import { Skeleton } from "@/components/ui/skeleton"

export function SkeletonDemo() {
  return (
    <div className="flex flex-col gap-3 w-64">
      <div className="flex items-center gap-3">
        <Skeleton className="h-10 w-10 rounded-full" />
        <div className="space-y-2 flex-1">
          <Skeleton className="h-3.5 w-full" />
          <Skeleton className="h-3 w-4/5" />
        </div>
      </div>
      <Skeleton className="h-32 w-full rounded-lg" />
      <Skeleton className="h-3.5 w-full" />
      <Skeleton className="h-3 w-3/5" />
    </div>
  )
}

Usage

Text lines

Mimic paragraph text with varying widths.

Avatar + text

Match the shape of an avatar with accompanying text lines.

Card skeleton

A full card-sized loading state.

Table rows

Skeleton rows for a data table loading state.

Props

PropTypeDefaultDescription
className*stringControls the size and shape of the skeleton. Use Tailwind height (h-*), width (w-*), and border-radius (rounded-*) utilities to match your content.
...propsReact.HTMLAttributes<HTMLDivElement>All standard HTML div attributes.

* Required props

Accessibility

  • Add aria-busy='true' on the parent container while content is loading to inform screen reader users.
  • Consider adding a visually-hidden text like 'Loading content' inside or near the skeleton area for screen readers.
  • Remove skeletons promptly when content loads — don't leave them as decorative placeholders.