Skip to content

Spin ​

A loading indicator that can be used standalone or wrap content with an overlaid mask; supports tips, progress, fullscreen and custom indicators.

Basic usage ​

size supports five tiers: xs / small / medium (default) / large / xl; the old abbreviations sm / md / lg remain supported.

Five sizes

Legacy abbreviations (sm / md / lg)

size also accepts arbitrary CSS sizes: plain numbers are interpreted as px, values with units (2rem / 40px / 10%) and calc() are used as-is.

Arbitrary sizes

Variants ​

variant provides three forms: ring (default border ring) / dot (three pulsing dots) / bars (three stretching bars). The size system applies to all variants.

ring / dot / bars

Inline dot next to text

Loading more

Tip text ​

Use the tip attribute for plain text or the named tip slot for rich content (the slot wins); tip-position controls placement (above / below default / before / after); hide-icon keeps only the text.

Tip text and four positions

Rich tip slot and hide-icon

Rich tip slot

Wrapping content ​

When wrapping content, the indicator and tip are centered with a translucent mask; show-overlay="false" disables the mask.

Wrapping content

Content area while loading

Disable mask (show-overlay="false")

Content stays fully visible

Delay anti-flicker ​

When a request finishes faster than the animation can be perceived, a flashing spinner is pure noise. delay (milliseconds) defers the indicator: if loading finishes within the window it never appears; aria-busy takes effect immediately regardless of the delay.

Fast requests don't flicker

200ms fast request → never appears; 2s slow request → appears after delay
Fast request (200ms, no flicker)Slow request (2s, delayed)

Custom indicator ​

The named icon slot replaces the default ring (size comes from the content itself); the rotate attribute spins the custom indicator — add rotate for regular SVG icons, omit it for GIFs / static SVGs.

icon slot and rotate

◈

Progress mode ​

Use the default form for unknown durations; when progress is known, percent (0-100) switches to a determinate progress ring (role="progressbar" + the aria-value trio); percent="auto" advances a simulated progress while loading (capped at 90%, restarts after finishing). For deterministic progress the Progress circle form is an alternative.

Determinate progress ring

Stepping progress and auto simulation

Progress +15

Paused ​

paused freezes looping animations (keeping the current frame) for screenshots / demos / frame inspection.

Paused comparison

Visual customization ​

Component-level CSS variables: --oas-spin-indicator-color / --oas-spin-track-color / --oas-spin-border-width / --oas-spin-duration / --oas-spin-mask-bg / --oas-spin-z-index. inherit-color makes the indicator follow the host text color; block makes the host occupy a full line.

CSS variable customization

inherit-color follows text color

Brand textSuccess text

Fullscreen ​

The fullscreen attribute enters a fullscreen centered mask; the imperative OASSpin.fullscreen() returns a { close } handle for async flows (calls stack, each handle closes independently).

Fullscreen loading (auto-closes after 2s)

Fullscreen 2sFullscreen with delay (3s)

Global default indicator ​

OASSpin.setDefaultIndicator(html) registers a branded loading animation: afterwards, newly created instances without an icon slot render the registered HTML instead of the built-in ring; pass null to restore. Priority: icon slot > global default > built-in ring.

Register a global indicator and spawn an instance

Register and spawnRestore built-in and spawn

Accessibility ​

  • The indicator has role="status" with a visually hidden screen-reader label (locale default "Loading…", reads tip when set, host aria-label wins)
  • Progress mode switches to role="progressbar" with aria-valuemin/max/now
  • Host aria-busy syncs immediately with spinning; for region loading, also mark the content container with aria-busy and point aria-describedby at the spin:
html
<section aria-busy="true" aria-describedby="page-spin">
  <oas-spin id="page-spin" spinning tip="Loading"></oas-spin>
  <!-- region content -->
</section>
  • Animations degrade to a static indicator when the OS enables "reduce motion" (prefers-reduced-motion)

API ​

oas-spin ​

Attributes ​

AttributeDescriptionTypeDefault
aria-labelScreen-reader text (synced with aria-busy)——
blockBlock level filling the container width——
delayAnti-flicker delay (ms): renders late after spinning is set; ends within delay = never showsstring—
fullscreenFullscreen loading (mask covers the viewport)——
hide-iconHide the default indicator (with slot="icon" or text-only)boolean—
inherit-colorIndicator inherits the host text color——
pausedPause rotation (freezes progress advance)——
percentProgress mode: number for explicit percent, or auto (simulated unknown-progress advance)string—
rotateWhether the custom indicator auto-rotates (off by default — rotates only when the attribute is present; leave unset for gif/static SVG to stay still)boolean—
show-overlayWhether to show the mask when wrapping contentstringtrue
sizeIndicator size: xs / small / medium (default) / large / xl; legacy abbreviations sm/md/lg remain supportedstringmedium
spinningWhether loading; when set, wraps content with an overlaid maskboolean—
tipLoading text (below the indicator standalone; centered on the mask when wrapping); rich content via slot="tip"string—
tip-positionText positionstringbelow
variantVisual variantstringring

Slots ​

NameDescription
defaultWrapped content (mask overlays in wrapping mode)
iconCustom indicator slot, replaces the default ring
tipRich loading text slot; overrides the tip attribute

CSS Variables ​

CSS VariableDescriptionDefault
--oas-spin-border-widthStroke width (ring border / progress stroke); 2px for xs and small3px
--oas-spin-durationAnimation duration0.8s
--oas-spin-indicator-colorIndicator colorvar(--oas-color-primary)
--oas-spin-mask-bgMask background (wrapping / fullscreen mode)color-mix(in srgb, var(--oas-color-bg) 70%, transparent)
--oas-spin-track-colorTrack color (ring base / progress track)var(--oas-color-bg-hover)
--oas-spin-z-indexFullscreen z-index3500

Static methods ​

MethodDescription
OASSpin.fullscreen(options?)Imperative fullscreen loading, returns { close() }; options: { tip?: string; delay?: number }
OASSpin.setDefaultIndicator(html | null)Register a global default indicator (affects newly created instances); null restores the built-in ring

The indicator uses role="status" (role="progressbar" + the aria-value trio in progress mode) with a built-in screen-reader label; host aria-busy syncs with spinning.

Released under the MIT OR Apache-2.0 License.