Skip to content

Attributes

Type Default Reflects
boolean false Yes

Show the shimmer overlay when present. Remove to reveal real content.

<!-- Loading state -->
<phantom-ui loading>...</phantom-ui>
<!-- Content revealed -->
<phantom-ui>...</phantom-ui>
Type Default Reflects
string shimmer Yes

Animation mode for the shimmer blocks. Four modes available:

  • shimmer – gradient sweep moving across each block (default)
  • pulse – opacity oscillation between full and faded
  • breathe – subtle scale and opacity breathing effect
  • solid – static blocks with no animation
<phantom-ui loading animation="pulse">...</phantom-ui>
<phantom-ui loading animation="breathe">...</phantom-ui>
<phantom-ui loading animation="solid">...</phantom-ui>

When the user’s system asks for reduced motion (prefers-reduced-motion: reduce), every mode automatically degrades to the static solid look: the infinite sweep, pulse and breathe animations stop, and nothing moves. In the default skeleton mode the blocks keep their static background. In overlay mode the block fill is transparent by design, so a static veil is kept over each measured element instead, and the refresh is still visible. No attribute or configuration needed.

Type Default Reflects
string skeleton Yes

Loading style.

  • skeleton (default) – hides the slotted content, measures it, and shows placeholder blocks. Use it for the first load when there is no data yet.
  • overlay – keeps the existing content visible and dimmed, and sweeps a light glint over each element. Use it for refresh / stale-while-revalidate states (a grid you already have data for and are refetching).
<phantom-ui loading mode="overlay">
<!-- the previous result stays visible (dimmed, not clickable) while it refreshes -->
</phantom-ui>

In overlay mode the content is not hidden, so it stays readable and in the accessibility tree (not made inert), and the light follows your DOM structure just like the skeleton. It is not clickable while loading (pointer-events: none), so users cannot act on stale data before the refresh lands. Dim the content with the --phantom-content-opacity CSS variable (default 0.5; set it to 1 for full opacity with light only). count and count-gap do not apply in this mode.

Type Default
number 0

Delay in seconds between each block’s animation start. Creates a wave effect where blocks animate one after another instead of all at once. Works with all animation modes.

<phantom-ui loading stagger="0.05">...</phantom-ui>
Type Default
number 0

Fade-out duration in seconds when loading ends. Instead of an instant switch, the shimmer overlay fades out smoothly. Set to 0 for instant reveal (default).

<phantom-ui loading reveal="0.3">...</phantom-ui>
Type Default
number 1

Number of skeleton rows to generate from a single template element. The component measures your slotted content once, then duplicates the skeleton blocks vertically. If the slotted element has a visible background, border, or box-shadow, these are replicated on each repeated row automatically. Useful for lists, tables, or feeds where you don’t have data yet to render multiple items.

<phantom-ui loading count="5">
<div class="user-row">
<img src="avatar.png" width="32" height="32" />
<span>John Doe</span>
<span>john@acme.io</span>
</div>
</phantom-ui>
Type Default
number 0

Gap in pixels between each repeated skeleton row. Only applies when count is greater than 1.

<phantom-ui loading count="5" count-gap="12">
<div class="feed-item">
<div class="avatar"></div>
<p>Activity description here</p>
</div>
</phantom-ui>
Type Default Reflects
string ltr Yes

Direction of the shimmer gradient sweep. Only applies to animation="shimmer" (the default).

  • ltr – left to right (default)
  • rtl – right to left
  • ttb – top to bottom
  • btt – bottom to top
<phantom-ui loading shimmer-direction="rtl">...</phantom-ui>
<phantom-ui loading shimmer-direction="ttb">...</phantom-ui>
Type Default
string rgba(128, 128, 128, 0.3)

Color of the animated gradient sweep that moves across each shimmer block. Only applies to animation="shimmer" (the default).

<phantom-ui loading shimmer-color="rgba(100, 200, 255, 0.4)">
...
</phantom-ui>
Type Default
string rgba(128, 128, 128, 0.2)

Background fill of each shimmer block. Applies to all animation modes.

<phantom-ui loading background-color="rgba(100, 200, 255, 0.1)">
...
</phantom-ui>
Type Default
number 1.5

Animation cycle duration in seconds.

<phantom-ui loading duration="2.5">...</phantom-ui>
Type Default
number 4

Border radius in pixels applied to elements that have border-radius: 0 (like text paragraphs). Elements with their own border radius (like circular avatars) keep their computed value.

<phantom-ui loading fallback-radius="8">...</phantom-ui>
Type Default Reflects
boolean false Yes

Outlines each measured block with an index, useful for inspecting how phantom-ui interprets your DOM. Leaf blocks get a pink outline and a numeric label (0, 1, 2…), container blocks get a blue outline and a C-prefixed label (C0, C1…). Toggle on temporarily during development to debug unexpected skeletons.

<phantom-ui loading debug>...</phantom-ui>
Type Default
string Loading

Accessible label announced by screen readers while loading. Set as aria-label on the host when loading is true, and removed when loading ends. Pair it with the automatic aria-busy to give assistive technology a meaningful description of what is loading.

<phantom-ui loading loading-label="Loading article">...</phantom-ui>
Type Default
boolean false

Measure inside the open shadow roots of slotted custom elements, instead of treating each component as a single block. Use it when wrapping components from a design system built with Stencil, Lit, or other Web Component tooling, where the structure lives inside shadow roots.

phantom-ui walks into each open shadow root, resolves default and named slots to their projected content, and hides the shadow content while loading. Closed shadow roots (mode: "closed") are not reachable.

<phantom-ui loading pierce-shadow>
<my-card>
<h3 slot="title">Placeholder</h3>
<p slot="body">A short bio goes here.</p>
</my-card>
</phantom-ui>

See the Design Systems guide for details and limitations.