Loading States

Spinner, skeleton, shimmer, and overlay patterns for indicating loading states.

Overview

Vanilla Breeze provides multiple loading state patterns for different contexts:

  • Spinner — Inline animated indicator for buttons, text, or overlays
  • Skeleton — Content-shaped placeholders that show layout structure
  • Shimmer — Animated overlay on existing content
  • Progress ring — Circular determinate/indeterminate progress

Inline Spinner

Use <loading-spinner> inline with text or inside buttons to indicate an ongoing operation.

Loading...

<!-- Inline spinner --> <loading-spinner data-size="s" aria-label="Loading"></loading-spinner> Loading... <!-- Button with spinner --> <button disabled> <loading-spinner data-size="s" aria-label="Loading"></loading-spinner> Saving... </button>

Skeleton Loading

Add data-loading="skeleton" to show children as gray placeholder shapes that preserve the layout structure.

Placeholder heading

Placeholder paragraph text that shows as a gray bar.

Another paragraph of placeholder text.

<!-- Skeleton loading state --> <div data-loading="skeleton"> <h2>Placeholder heading</h2> <p>Placeholder paragraph text that shows as a gray bar.</p> <p>Another paragraph of placeholder text.</p> </div>

Shimmer Overlay

The data-loading attribute (without a value, or with "minimal" or "hide") adds an animated overlay on top of existing content.

<!-- Shimmer overlay on existing content --> <div data-loading> <h2>Real content here</h2> <p>Content is dimmed with a shimmer animation overlay.</p> </div> <!-- Minimal pulse variant --> <div data-loading="minimal"> <p>Subtle pulse effect instead of sweeping shimmer.</p> </div> <!-- Hidden content variant --> <div data-loading="hide"> <p>Content is completely hidden (not just dimmed).</p> </div>

Spinner Overlay

Add data-overlay to a spinner to center it over a parent container with a translucent backdrop.

<!-- Spinner overlay on a section --> <div style="position: relative; min-height: 200px;"> <p>Content behind the overlay.</p> <loading-spinner data-overlay data-size="l" aria-label="Loading section"></loading-spinner> </div>

Progress Indicators

For determinate progress, use <progress-ring> or the native <progress> element.

67% 67%
<!-- Determinate progress ring --> <progress-ring style="--progress: 67" data-size="l" role="progressbar" aria-valuenow="67" aria-valuemin="0" aria-valuemax="100"> <span>67%</span> </progress-ring> <!-- Indeterminate progress ring --> <progress-ring data-indeterminate data-size="l" role="progressbar" aria-label="Loading"></progress-ring> <!-- Native progress bar --> <progress value="67" max="100">67%</progress>

Usage Guidelines

  • Spinner: Use for short, indeterminate operations (fetching data, saving)
  • Skeleton: Use for initial page loads where content structure is known
  • Shimmer: Use for refreshing existing content (data reload)
  • Progress ring: Use when you can track completion percentage
  • All patterns respect prefers-reduced-motion: reduce
  • Always include appropriate ARIA attributes for screen readers

Related

loading-spinner

CSS-only spinner element

progress-ring

Circular progress indicator

progress

Native progress bar

Skeleton Pattern

Full skeleton loading pattern