Skip to content
The Membrane Palette
Feedbackstable

Skeleton

Placeholder text lines, circles and blocks that hold a layout's shape while content loads; they pulse in place under reduced motion.

Examples

Loading card

Loading workshop…
HTML for “Loading card”
<div class="mp-card" aria-busy="true" aria-describedby="skeleton-status">
  <span class="mp-visually-hidden" id="skeleton-status" role="status">Loading workshop…</span>
  <div class="mp-skeleton" data-variant="block" aria-hidden="true"></div>
  <div aria-hidden="true">
    <div class="mp-skeleton" data-variant="text" style="--mp-skeleton-width: 40%"></div>
    <div class="mp-skeleton" data-variant="text"></div>
    <div class="mp-skeleton" data-variant="text"></div>
  </div>
  <div class="mp-cluster" aria-hidden="true">
    <div class="mp-skeleton" data-variant="circle"></div>
    <div class="mp-skeleton" data-variant="text" style="--mp-skeleton-width: 8rem"></div>
  </div>
</div>

Guidance

Use skeletons when you know the shape of what's coming (a card, a list, a profile) and it takes longer than ~300ms. They prevent layout shift and feel calmer than a spinner. For an unknown or short wait, use a spinner.

Accessibility

  • Skeleton shapes are aria-hidden="true"; the loading region has aria-busy="true" and a visually hidden role="status" message.
  • Remove aria-busy (and the skeletons) in the same update that inserts the content.
  • Under prefers-reduced-motion the sweeping shimmer becomes a slow in-place pulse, so the placeholder never looks finished.

API

Skeleton classes
ClassKind
.mp-skeletonroot
Skeleton attributes
AttributeValues
data-varianttext · circle · block
Skeleton component tokens
TokenDefaultLight · dark
--mp-skeleton-width100%—
--mp-skeleton-height1rem—

Design tokens consumed: --color-bg-active --color-bg-hover --duration-loop --ease-in-out --radius-full --radius-lg --radius-sm --space-10 --space-32

Source