Skeleton
Loading placeholder with shimmer animation.
<arc-skeleton> Overview
>
Skeleton is a loading placeholder that mimics the shape of content before it arrives, reducing perceived wait times and preventing layout shift. It uses a shimmer animation — a linear gradient that sweeps left to right at 1.8-second intervals — to signal that data is being loaded. This approach is less intrusive than a spinner and gives users a preview of the page structure.
Three variant shapes cover common content patterns: `text` renders a single-line bar (full width, 1em height) ideal for paragraph placeholders, `circle` produces a perfect circle for avatar placeholders (height auto-matches width when not explicitly set), and `rect` creates a rectangular block for images, cards, or media thumbnails. Custom `width` and `height` properties let you match the exact dimensions of the content being loaded.
The shimmer gradient uses `--bg-elevated` and `--border-subtle` tokens to ensure the animation blends naturally with both light and dark themes. The component sets `role="status"`, `aria-label="Loading"`, and `aria-busy="true"` for screen reader users who cannot see the visual animation.Guidelines
When to use
- Match skeleton dimensions to the actual content they replace to prevent layout shift
- Combine multiple skeletons to represent a full content layout (avatar + text lines)
- Use the text variant in a stack with varying widths for realistic paragraph placeholders
- Use the circle variant sized to match your avatar component dimensions
- Remove skeletons immediately when content loads — do not add artificial delays
When not to use
- Do not use skeletons for actions that take under 200ms — the flash is more distracting than helpful
- Do not Stack more than 5-6 skeleton lines — it looks like a broken page rather than a loading state
- Do not use a rect skeleton without setting width and height — it will collapse to zero size
- Do not mix skeletons with spinners on the same screen — choose one loading pattern
- Do not animate skeleton opacity on top of the shimmer — the dual animation is visually noisy
Features
- Three shape variants: text (line), circle (avatar), and rect (block)
- Smooth shimmer animation using a sweeping linear gradient at 1.8s intervals
- Custom width and height properties for precise content-matching dimensions
- Circle variant auto-matches height to width when height is not set
- Theme-aware shimmer using `--bg-elevated` and `--border-subtle` tokens
- Built-in accessibility: `role="status"`, `aria-label`, and `aria-busy` attributes
- CSS part (skeleton) for external animation or style overrides
Preview
Usage
<arc-skeleton variant="text" width="200px"></arc-skeleton>
<arc-skeleton variant="circle" width="48px"></arc-skeleton>
<arc-skeleton variant="rect" width="300px" height="120px"></arc-skeleton> import { Skeleton } from '@arclux/arc-ui-react';
export default function Example() {
return (
<>
<Skeleton variant="text" width="200px" />
<Skeleton variant="circle" width="48px" />
<Skeleton variant="rect" width="300px" height="120px" />
</>
);
} <script setup>
import { Skeleton } from '@arclux/arc-ui-vue';
</script>
<template>
<Skeleton variant="text" width="200px" />
<Skeleton variant="circle" width="48px" />
<Skeleton variant="rect" width="300px" height="120px" />
</template> <script>
import { Skeleton } from '@arclux/arc-ui-svelte';
</script>
<Skeleton variant="text" width="200px" />
<Skeleton variant="circle" width="48px" />
<Skeleton variant="rect" width="300px" height="120px" /> import { Component } from '@angular/core';
import { Skeleton } from '@arclux/arc-ui-angular';
@Component({
imports: [Skeleton],
template: `
<arc-skeleton variant="text" width="200px"></arc-skeleton>
<arc-skeleton variant="circle" width="48px"></arc-skeleton>
<arc-skeleton variant="rect" width="300px" height="120px"></arc-skeleton>
`,
})
export class MyComponent {} import { Skeleton } from '@arclux/arc-ui-solid';
export default function Example() {
return (
<>
<Skeleton variant="text" width="200px" />
<Skeleton variant="circle" width="48px" />
<Skeleton variant="rect" width="300px" height="120px" />
</>
);
} import { Skeleton } from '@arclux/arc-ui-preact';
export default function Example() {
return (
<>
<Skeleton variant="text" width="200px" />
<Skeleton variant="circle" width="48px" />
<Skeleton variant="rect" width="300px" height="120px" />
</>
);
} <!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-skeleton — requires skeleton.css + base.css (or arc-ui.css) -->
<div class="arc-skeleton">
<div
class="skeleton"
role="status"
aria-label="Loading"
aria-busy="true"
></div>
</div> <!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-skeleton — self-contained, no external CSS needed -->
<div class="arc-skeleton" style="display: block">
<div
style="background: linear-gradient(
90deg,
rgb(17, 17, 22) 25%,
rgb(24, 24, 30) 37%,
rgb(17, 17, 22) 63%
); background-size: 200% 100%; animation: shimmer 1.8s ease-in-out infinite"
role="status"
aria-label="Loading"
aria-busy="true"
></div>
</div> API
-
variant'text' | 'circle' | 'rect''text' - Shape of the skeleton: text for lines, circle for avatars, rect for blocks
-
widthstring'' - CSS width value (e.g. "200px", "100%")
-
heightstring'' - CSS height value; circle auto-matches width when omitted
-
countnumber1 - Renders multiple skeleton items stacked vertically with spacing. Useful for placeholder lists.