Skip to content

Skeleton ​

A loading placeholder component for representing content that has not loaded yet. Use it to reduce layout shift and provide immediate visual structure while data is fetched.

Variants ​

Rectangle (Default) ​

PreviewCode
RTL
html
<ore-skeleton width="100%" height="1rem"></ore-skeleton> <ore-skeleton width="16rem" height="10rem"></ore-skeleton>

Circle ​

PreviewCode
RTL
html
<ore-skeleton variant="circle" size="sm"></ore-skeleton>
<ore-skeleton variant="circle" size="lg"></ore-skeleton>
<ore-skeleton variant="circle" width="3.5rem" height="3.5rem"></ore-skeleton>

Text ​

PreviewCode
RTL
html
<ore-skeleton variant="text" lines="3" width="100%"></ore-skeleton>
<ore-skeleton variant="text" lines="2" width="70%"></ore-skeleton>

Sizes ​

PreviewCode
RTL
html
<ore-skeleton size="sm" width="14rem"></ore-skeleton>
<ore-skeleton size="md" width="14rem"></ore-skeleton>
<ore-skeleton size="lg" width="14rem"></ore-skeleton>

Common Patterns ​

Card Placeholder ​

PreviewCode
RTL
html
<ore-card style="padding: var(--size-4); width: 20rem;">
  <ore-skeleton width="100%" height="10rem" style="margin-bottom: var(--size-4)"></ore-skeleton>
  <ore-skeleton variant="text" lines="3" width="100%"></ore-skeleton>
</ore-card>

Rectangle and circle skeletons fill their rendered host box, including externally sized grid, flex, card-media, and aspect-ratio layouts. Set dimensions on the component; styling the stack or bone parts is unnecessary.

List Item Placeholder ​

PreviewCode
RTL
html
<div style="display: grid; gap: var(--size-3); width: 100%; max-width: 28rem;">
  <div style="display: flex; align-items: center; gap: var(--size-3);">
    <ore-skeleton variant="circle" width="2.25rem" height="2.25rem"></ore-skeleton>
    <div style="flex: 1; display: grid; gap: var(--size-2);">
      <ore-skeleton variant="text" width="40%"></ore-skeleton>
      <ore-skeleton variant="text" width="70%"></ore-skeleton>
    </div>
  </div>
</div>

Animation Control ​

Use animated="false" for static placeholders.

PreviewCode
RTL
html
<ore-skeleton width="16rem" height="1rem"></ore-skeleton>
<ore-skeleton width="16rem" height="1rem" animated="false"></ore-skeleton>

Striped ​

Add striped to replace the shimmer with a diagonal stripe pattern. Useful for designers building page layouts: the high-contrast stripes make it immediately obvious where content placeholders are, without relying on animation.

PreviewCode
RTL
html
<ore-card padding="md" style="width: 280px;">
  <!-- Hero image area -->
  <ore-skeleton striped width="100%" height="160px" style="border-radius: 0; display: block;"></ore-skeleton>

  <ore-grid gap="md" style="margin-top: var(--size-4);">
    <!-- Avatar + author line -->
    <div style="display: flex; align-items: center; gap: var(--size-2);">
      <ore-skeleton striped variant="circle" width="2rem" height="2rem"></ore-skeleton>
      <ore-skeleton striped variant="text" width="6rem"></ore-skeleton>
    </div>

    <!-- Title -->
    <ore-skeleton striped width="90%" height="1.125rem"></ore-skeleton>

    <!-- Body text lines -->
    <ore-skeleton striped variant="text" lines="3" width="98%"></ore-skeleton>

    <!-- Action button -->
    <ore-skeleton striped width="7rem" height="2rem" style="border-radius: var(--rounded-lg);"></ore-skeleton>
  </ore-grid>
</ore-card>

The spacing between lines is adjustable via the --skeleton-stripe-size CSS custom property:

html
<ore-skeleton striped width="100%" height="2rem" style="--skeleton-stripe-size: 16px"></ore-skeleton>

API Reference ​

Attributes

AttributeTypeDefaultDescription
variant'rect' | 'circle' | 'text''rect'Visual shape preset
size'sm' | 'md' | 'lg'N/AHeight preset for rect/text; diameter for circle
widthstringN/AWidth override (e.g. 12rem, 70%)
heightstringN/AHeight override
radiusstringN/ABorder-radius override
animatedbooleantrueSet animated="false" to disable shimmer
linesnumber1Number of text lines (variant="text")
stripedbooleanfalseDiagonal stripe pattern instead of shimmer

Parts

PartDescription
stackOuter container wrapping all bones
boneIndividual skeleton bone element

Events

This component does not emit custom events.

CSS Custom Properties

PropertyDescriptionDefault
--skeleton-bgBase colorvar(--color-contrast-200)
--skeleton-highlightShimmer highlight colorvar(--color-contrast-100)
--skeleton-radiusBorder radiusvar(--rounded-lg)
--skeleton-sizeCircle fallback sizevar(--size-10)
--skeleton-widthComponent width100%
--skeleton-heightComponent heightvar(--size-4)
--skeleton-line-gapGap between text linesvar(--size-2)
--skeleton-last-line-widthWidth of the final text line60%
--skeleton-durationShimmer animation duration1.6s
--skeleton-stripe-sizeSVG tile size controlling diagonal stripe density (striped)8px
--skeleton-stripe-colorColor of the diagonal lines and dashed border (striped)var(--color-contrast-400)

Performance ​

The shimmer animation is automatically paused when the element scrolls out of the viewport, using an IntersectionObserver. This prevents off-screen animations from consuming GPU resources.

Animation can also be disabled entirely with animated="false": useful for static mockups or when the parent already shows a loading spinner.

Accessibility ​

Skeleton placeholders are decorative and non-interactive. Each bone is marked with aria-hidden="true" so screen readers skip over them entirely; no content is announced and no focusable roles or tab stops are exposed. The shimmer animation respects prefers-reduced-motion: reduce and is suppressed automatically when the user has requested reduced motion. In forced-colors environments the bone renders with ButtonFace background and ButtonText border for high-contrast visibility.

  • Progress for explicit operation progress states
  • Card for content containers commonly paired with placeholders
  • Text for loaded content replacing text skeleton lines