Skeleton
v1.0.0CSS 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%;