Skeleton

v1.0.0

CSS loading placeholders that reserve content geometry.

Loading region

A skeleton reserves expected content geometry; a skeleton screen represents a larger region. Use progress for measurable completion.

Set aria-busy="true" on the stable region and aria-hidden="true" on placeholders. Add one status only when needed. Never apply skeleton classes to real controls; CSS cannot remove them from keyboard order.

Loading profile…

<section aria-busy="true" aria-describedby="profile-loading-status">
	<p id="profile-loading-status" role="status">Loading profile…</p>
	<div aria-hidden="true">
		<span class="skeleton skeleton-avatar"></span>
		<div class="skeleton-lines">
			<span class="skeleton skeleton-headline skeleton-sm"></span>
			<span class="skeleton skeleton-text w-50"></span>
		</div>
	</div>
</section>

Variants

Combine .skeleton with a shape and optional .skeleton-sm, .skeleton-md or .skeleton-lg size.

<span class="skeleton skeleton-headline" aria-hidden="true"></span>
<span class="skeleton skeleton-text" aria-hidden="true"></span>
<span class="skeleton skeleton-avatar" aria-hidden="true"></span>
<span class="skeleton skeleton-image" aria-hidden="true"></span>
<span class="skeleton skeleton-pill" aria-hidden="true"></span>
<span class="skeleton skeleton-square" aria-hidden="true"></span>

Multi-line text

Wrap .skeleton-text items in .skeleton-lines. Children set the count; variables control gap and final width.

<div class="skeleton-lines w-75" aria-hidden="true">
	<span class="skeleton skeleton-text"></span>
	<span class="skeleton skeleton-text"></span>
	<span class="skeleton skeleton-text"></span>
	<span class="skeleton skeleton-text"></span>
</div>

Dimensions, ratios and shapes

Use width utilities, .skeleton-aspect-square, .skeleton-aspect-video and radius utilities. Set component variables for exact dimensions.

<span class="skeleton skeleton-text w-50" aria-hidden="true"></span>
<span class="skeleton skeleton-square skeleton-lg rounded-circle" aria-hidden="true"></span>
<span class="skeleton skeleton-aspect-video w-25" aria-hidden="true"></span>
<span
	class="skeleton"
	style="--skeleton-width: 8rem; --skeleton-height: 4rem; --skeleton-border-radius: 1rem;"
	aria-hidden="true"></span>

Match final content dimensions to prevent layout shift.

Skeleton screen compositions

Cards and responsive grids

Lists

Tables

Forms

Compositions support both themes, forced colors and reduced motion without changing geometry.

Replacing the loading state

Replace the composition atomically with one loaded, empty or error state. Keep the region mounted, set aria-busy="false" and preserve focus when possible. Never layer skeletons over real controls. Use Empty State for no content and Alert for failure.

Use at most one non-duplicated status per region.

CSS Variables

Override these variables on the component or an ancestor.

--skeleton-width: 100%;
--skeleton-height: 1rem;
--skeleton-size: 2.5rem;
--skeleton-font-size: var(--font-size);
--skeleton-line-height: var(--line-height-sm);
--skeleton-control-height: 2.5rem;
--skeleton-aspect-ratio: auto;
--skeleton-border-radius: var(--border-radius-sm);
--skeleton-base-color: color-mix(in srgb, var(--text-color) 14%, var(--bg-surface));
--skeleton-highlight-color: color-mix(in srgb, var(--text-color) 5%, var(--bg-surface));
--skeleton-animation-duration: 1.6s;
--skeleton-animation-easing: ease-in-out;
--skeleton-line-gap: var(--spacer-2);
--skeleton-last-line-width: 65%;