Skip to content
buttery

v1.0.0

Source on GitHub

Version 1.0.0

Skeleton

A shimmering placeholder for something still loading, shaped like the text or block it stands in for.

import { Skeleton } from "@butteryui/core";

Demo

When to use it

Use it for

  • A part whose content is on its way, such as a metric's value or a card's lines, so the layout holds still when it arrives
  • Building a component's loading state: give each part a skeleton in its own place

Not for

  • Loads that usually finish in under 300ms: show nothing, or a LoadingPill, which waits
  • A whole chart: charts take loading and show a LoadingPill in their box

Examples

Loading lines

Three lines standing in for a paragraph that's still loading under its heading, the last one shorter.

Tasting notes

Loading metric

A metric that shows a skeleton where its value goes until the value arrives, and again while it refreshes.

Wholesale orders

Text roles

A line for each of a few text roles, as tall as the role's trimmed line and as wide as its text, and a block the CSS sizes.

title-lg

label

body

caption

A block, sized by its CSS

Variants and states

Lines of text

Each line takes its role's height, trimmed like the text, and the width of its placeholder text.

A block

Without a variant, the CSS around it sets its size.

Props

Skeleton

PropTypeDefaultDescription
variantTextVariantThe type role of the text it stands in for: it takes that role's line, trimmed the same way, so the text that replaces it lands in its place. Leave it out for a block the CSS around it sizes.
textstringPlaceholder text, about as long as what it stands in for, that sets its width. Without it, it fills its row.

It also takes Omit<ComponentPropsWithRef<"span">, "children">.

Accessibility

Hidden from screen readers. Mark the region that's loading with aria-busy, and announce the load with a LoadingPill or a status message if it takes a while.

It takes no keyboard input of its own.

Motion

It cycles its states every few seconds and pauses while it's offscreen.

With reduced motion: It holds still: the shimmer no longer sweeps across it.

Layout

With a variant it's one line of that text role, trimmed the same way, so the text that replaces it lands in its place: as wide as its placeholder text, or the whole row when it has none. Without a variant it's a block that fills its row and takes its height from your CSS. It has no hit area.